TypeScript / AngularJS - Использование службы ngResource

Мне трудно инициализировать новый объект ресурса.

Получение данных из REST API работает просто отлично.

Ошибка выдается в следующей строке кода:

var newRoom = new this.lobbyStorage.LobbyRoom();

со следующим сообщением:

"this. $ ngResource не является функцией"

Я пробовал довольно много вещей, но ничего, что привело бы меня к положительному результату.

Решение

Для функций, созданных с использованием синтаксиса new Function (...) или просто Function (...), свойству name присвоено пустое значение. В следующих примерах создаются анонимные функции, поэтому name возвращает пустую строку:

Вы не можете изменить имя функции, это свойство доступно только для чтения:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name


лобби-storage.ts

module lobby.services {
  export class LobbyStorage {

    private baseUrl : string = 'http://localhost:2999'; /*this.appConstant.baseUrl + '/lobby';*/

    public static $inject = [
      '$http',
      '$resource'
    ];

    constructor(private $http: ng.IHttpService, private $ngResource : ng.resource.IResourceService /*,private appConstant*/) {

    }

    public LobbyRoom() : ng.resource.IResourceClass<ng.resource.IResource<any>> {
      return this.$ngResource(this.baseUrl + '/lobby/:id', { id: '@id' });
    }
  }
}

лобби-modules.ts

///<reference path='../../typings/tsd.d.ts' />
module lobby {
  'use strict';

  /* @ngdoc object
   * @name lobby
   * @description
   *
   */
  angular
    .module('lobby', [
      'ngRoute',
      'ngResource'
    ])
    .service('lobbyStorage', lobby.services.LobbyStorage)
  /* .constant('appConstant', lobby.constants.Constants.Default);*/
}

лобби-controller.ts

/// <reference path='../_lobby.ts' />

module lobby.controllers {
  'use strict';

  class LobbyCtrl {

    public lobbyData : Array<string>;
    public gameCreation : boolean = true;
    public currentItem : any = {};

    // $inject annotation.
    // It provides $injector with information about dependencies to be injected into constructor
    // it is better to have it close to the constructor, because the parameters must match in count and type.
    // See http://docs.angularjs.org/guide/di
    public static $inject = [
      '$scope',
      '$log',
      'lobbyStorage'
    ];

    // dependencies are injected via AngularJS $injector
    constructor(private $scope, private $log : ng.ILogService, private lobbyStorage) {
      this.init();
    }

    // Initializer function
    private init(){
      this.initializeLobbyData();
    }

    public createRoom() : void{
      var newRoom = new this.lobbyStorage.LobbyRoom();
      newRoom.name = this.currentItem.name;
      newRoom.$save();
    }

    public initializeLobbyData(){
      var res = this.lobbyStorage.LobbyRoom().query(
        () => this.lobbyData = res,
        () => this.lobbyData[0] = "Error"
      );
    }
  }


  /**
  * @ngdoc object
  * @name lobby.controller:LobbyCtrl
  *
  * @description
  *
  */
  angular
    .module('lobby')
    .controller('LobbyCtrl', LobbyCtrl);
}

2 ответа

Решение

Дело в том, что мы вызываем функцию, а не конструктор

// wrong
// this is not constructor call
var newRoom = new this.lobbyStorage.LobbyRoom()

// ok
// just a method
var newRoom = this.lobbyStorage.LobbyRoom()

Есть неработающий пример (просто нажмите Run)

var x = new lobby.services.LobbyStorage({}, (str) => {return str});

try {
  var y = new x.LobbyRoom();
}
catch (ex){
  alert(ex);    
}

Если бы мы не называли его конструктором, а методом - он будет работать:

var x = new lobby.services.LobbyStorage({}, (str) => {return str});

var y =  x.LobbyRoom();

alert(y);

проверьте эту версию здесь

Когда вы вызываете LobbyRoom с "новым", подразумевается, что вы создаете новый объект. 'This' LobbyRoom будет использовать новый объект, который вы создаете, и не будет ссылаться на класс. Вы должны сделать одну из двух вещей. Либо создайте класс LobbyRoom, либо вызовите LobbyRoom без использования "new", например так:

var newRoom = this.lobbyStorage.LobbyRoom();
Другие вопросы по тегам