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})
如果我打印结果,我可以看到:
Resource {id: 1,details: 'somestuff'}
相比之下,我希望有:
MyObject {id: 1,details: 'somestuff'}
这将使我能够访问someMethod以及我为此类定义的所有其他方法.
难道我做错了什么?
提前致谢.
解决方法
>在工厂内部创建了一个Resource函数(它是$resource provider),并在调用$resource时返回.
资源具有以下结构(让我们想象一下,我们只想获得它所拥有的方法的高级视图,而不是每个方法的工作方式)
function Resource(value) { ... } Resource.prototype.toJSON = function () { ... } Resource.prototype.bind = function () { ... }
>我还看到$resource函数在第3个参数中接收要在Resource函数上设置的附加动作(与某些默认动作合并),我看到你正在发送一个额外的更新方法,所以对象有以下结构
将更新与默认操作合并:
{ '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的原型设置一个方法,即
Resource.get = function () { ... } Resource.save = function () { ... } Resource.update = function () { ... } ... Resource.prototype.$get = function () { ... } Resource.prototype.$save = function () { ... } Resource.prototype.$update = function () { ... } ...
现在回到你的代码,你从MyObjectResource扩展一个新函数MyObject,其中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内部才会发生,这不是MyObjectResource Source的实例),如果我们做新的MyObjectResource()则无法访问someMethod因为它实际上是在“子类”中定义的.
但是我们可以创建一个MyObject实例,并且由于coffeescript的扩展创建了链接,实例可以通过MyObjectResource.prototype访问相同的内容.$get,所以:
var instance = new MyObject() instance.$get({id: 1}); // works because of the link created between the prototypes instance.someMethod(); // also works