使用CoffeeScript,Angular和$ resource,我创建了以下工厂:
angular.module('myapp', ['ngResource']).factory 'MyObject', ['$resource', ($resource) ->
MyObjectResource = $resource '/api/my_object/:id', {
id: '@id'
}, {
update:
method: 'PUT'
}
class MyObject extends MyObjectResource
someMethod: ->
dosomething
]
问题在于,当我从API加载对象时,我得到一个Resource
对象而不是MyObject
对象,这是一个问题,因为我无法访问其他对象方法
以下是获取对象的代码:
result = MyObject.get({id: 1})
如果我打印result
,我可以看到:
Resource {id: 1, details: 'somestuff'}
相比之下,我希望有:
MyObject {id: 1, details: 'somestuff'}
这将使我能够访问someMethod
以及我为此类定义的所有其他方法。
我做错了吗?
提前致谢。
答案 0 :(得分:5)
在快速查看源代码后,我看到以下关系:
Resource
函数($resource
提供程序),并在调用$resource
时返回。资源具有以下结构(让我们想象一下,我们只想了解它所拥有的方法的高级视图,而不是每种方法的工作方式)
function Resource(value) { ... }
Resource.prototype.toJSON = function () { ... }
Resource.prototype.bind = function () { ... }
$resource
函数在第3个参数中接收到要在Resource
函数上设置的其他操作(与某些默认操作合并),我看到你是'发送额外的update
方法,因此该对象具有以下结构将update
与默认操作合并:
{
'get': {method: 'GET'},
'save': {method: 'POST'},
'query': {method: 'GET', isArray: true},
'remove': {method: 'DELETE'},
'delete': {method: 'DELETE'},
// added by the user
update: { method: 'PUT' }
}
$resource
为Resource
函数的此哈希的每个属性设置一个方法,并在方法名称前附加Resource
$
的原型设置方法,即< / p>
Resource.get = function () { ... }
Resource.save = function () { ... }
Resource.update = function () { ... }
...
Resource.prototype.$get = function () { ... }
Resource.prototype.$save = function () { ... }
Resource.prototype.$update = function () { ... }
...
现在返回到您的代码,您需要从MyObject
扩展新功能MyObjectResource
,其中MyObjectResource
是调用$resource
的结果,即Resource
在上面看到的函数中,coffeescript的extend
实际上会将MyObjectResource
上定义的所有属性复制到MyObject
,并且还会隐藏[[Prototype]]
属性MyObject.prototype
指向MyObjectResource.prototype
:
MyObjectResource
prototype -------> MyObjectResource.prototype
$get
get $save
save toJSON
... ...
^
|
MyObject |
prototype -------> MyObject.prototype
get (reference) someMethod
set (reference)
...
这就是为什么你可以执行MyObject.get
的原因,因为它现在引用了MyObjectResource.get
,即MyObject.get === MyObjectResource.get
这是有趣的部分,调用MyObject.get
将返回MyObjectResrouce
的实例(这实际上已经被编码,但只有当MyObject.get
this
内部没有时才会发生MyObjectResource
Source的实例,如果我们new MyObjectResource()
无法访问someMethod
,因为它实际上是在&#34中定义的;子&#34;
但是我们可以创建MyObject
的实例,并且由于coffeescript extend
创建的链接,实例可以访问相同的get
到MyObjectResource.prototype.$get
,所以:
var instance = new MyObject()
instance.$get({id: 1}); // works because of the link created between the prototypes
instance.someMethod(); // also works