为什么 Angular $resource return 是 Resource 对象而不是 class 对象?
Why does Angular $resource return a Resource object instead of the class object?
使用 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
以及我为此 class 定义的所有其他方法。
我是不是做错了什么?
提前致谢。
快速查看源代码后,我看到以下关系:
- 在工厂内部创建了一个
Resource
函数(它是 $resource
提供者)并且在调用 $resource
时被 return 编辑。
资源具有以下结构(假设我们只想了解它具有什么方法而不是每个方法的作用)
function Resource(value) { ... }
Resource.prototype.toJSON = function () { ... }
Resource.prototype.bind = function () { ... }
- 我还看到
$resource
函数在第三个参数中接收要在 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
的原型上附加一个 $
方法名称,即
Resource.get = function () { ... }
Resource.save = function () { ... }
Resource.update = function () { ... }
...
Resource.prototype.$get = function () { ... }
Resource.prototype.$save = function () { ... }
Resource.prototype.$update = function () { ... }
...
现在 return 正在对您的代码进行扩展 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
将 return MyObjectResrouce
的一个实例(这实际上是硬编码的,但只有在 MyObject.get
this
内部时才会发生不是 MyObjectResource
Source 的实例),如果我们这样做 new MyObjectResource()
就没有办法访问 someMethod
因为它实际上是在 "subclass".[=52 中定义的=]
但是我们可以创建 MyObject
的实例,并且由于 coffeescript extend
创建的链接,该实例可以通过 MyObjectResource.prototype.$get
访问相同的 get
,所以:
var instance = new MyObject()
instance.$get({id: 1}); // works because of the link created between the prototypes
instance.someMethod(); // also works
使用 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
以及我为此 class 定义的所有其他方法。
我是不是做错了什么?
提前致谢。
快速查看源代码后,我看到以下关系:
- 在工厂内部创建了一个
Resource
函数(它是$resource
提供者)并且在调用$resource
时被 return 编辑。
资源具有以下结构(假设我们只想了解它具有什么方法而不是每个方法的作用)
function Resource(value) { ... }
Resource.prototype.toJSON = function () { ... }
Resource.prototype.bind = function () { ... }
- 我还看到
$resource
函数在第三个参数中接收要在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
的原型上附加一个 $
方法名称,即
Resource.get = function () { ... }
Resource.save = function () { ... }
Resource.update = function () { ... }
...
Resource.prototype.$get = function () { ... }
Resource.prototype.$save = function () { ... }
Resource.prototype.$update = function () { ... }
...
现在 return 正在对您的代码进行扩展 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
将 return MyObjectResrouce
的一个实例(这实际上是硬编码的,但只有在 MyObject.get
this
内部时才会发生不是 MyObjectResource
Source 的实例),如果我们这样做 new MyObjectResource()
就没有办法访问 someMethod
因为它实际上是在 "subclass".[=52 中定义的=]
但是我们可以创建 MyObject
的实例,并且由于 coffeescript extend
创建的链接,该实例可以通过 MyObjectResource.prototype.$get
访问相同的 get
,所以:
var instance = new MyObject()
instance.$get({id: 1}); // works because of the link created between the prototypes
instance.someMethod(); // also works