我有一个使用 $resource
定义的模型,我已成功加载该模型。
正如所 promise 的,每个加载的实例都是我定义的类的实例。
(下面的示例来自 Angular 文档。其中,User.get
生成一个 instanceof User
对象。)
var User = $resource('/user/:userId', {userId:'@id'});
但是,想象一下每个用户都像这样通过网络:
{
"username": "Bob",
"preferences": [
{
"id": 1,
"title": "foo",
"value": false
}
]
}
我定义了一个 Preference
工厂,它向 Preference
对象添加了有值(value)的方法。但是当用户加载时,这些首选项
自然不是首选项
。
我尝试过这个:
User.prototype.constructor = function(obj) {
_.extend(this, obj);
this.items = _.map(this.preferences, function(pref) {
return new Preference(pref);
});
console.log('Our constructor ran'); // never logs anything
}
但它没有任何效果并且从不记录任何内容。
如何使我的User
的preferences
数组中的每一项成为Preference
的实例?
最佳答案
$resource 是一个简单的实现,缺少这样的东西。
User.prototype.constructor
不会做任何事情;与其他库不同,Angular 并不试图表现得像面向对象。这只是 JavaScript。
..但幸运的是,你有 Promise 和 javascript :-)。您可以采用以下方法:
function wrapPreferences(user) {
user.preferences = _.map(user.preferences, function(p) {
return new Preference(p);
});
return user;
}
var get = User.get;
User.get = function() {
return get.apply(User, arguments).$then(wrapPreferences);
};
var $get = User.prototype.$get;
User.prototype.$get = function() {
return $get.apply(this, arguments).$then(wrapPreferences);
};
您可以将其抽象为一个方法,该方法可以装饰任何资源的方法:它需要一个对象、一个方法名称数组和一个装饰器函数。
function decorateResource(Resource, methodNames, decorator) {
_.forEach(methodNames, function(methodName) {
var method = Resource[methodName];
Resource[methodName] = function() {
return method.apply(Resource, arguments).$then(decorator);
};
var $method = Resource.prototype[methodName];
Resource.prototype[methodName] = function() {
return $method.apply(this, arguments).$then(decorator);
};
});
}
decorateResource(User, ['get', 'query'], wrapPreferences);
关于angularjs - 如何扩展 AngularJS 资源 ($resource) 的构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16452277/