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();