ngResource 中的虚拟属性
Posted
技术标签:
【中文标题】ngResource 中的虚拟属性【英文标题】:Virtual attributes in ngResource 【发布时间】:2014-07-25 03:37:32 【问题描述】:是否可以向 ngResource 添加虚拟属性? 我创建了这样的服务
app.factory('Person', ['$resource', function($resource)
return $resource('api/path/:personId',
personId: '@_id'
,
update:
method: 'PUT'
);
])
Person
有一个属性name
和一个属性surname
。
我想通过添加虚拟属性 fullname
返回 resource.name + resource surname
来检索 fullname
。
我知道我可以将它添加到控制器中,但是将它添加到服务中会使其更便携。
我试过这样的东西
app.factory('Person', ['$resource', function($resource)
return $resource('api/path/:personId',
personId: '@_id'
,
update:
method: 'PUT'
,
fullname: function(resource)
return resource.name + ' ' + resource.surname;
);
);
])
但它不起作用。
【问题讨论】:
【参考方案1】:Khanh TO 让我找到了可行的答案,但是,正如in this Angular ticket 所解释的,在拦截器中,您必须处理并返回response.resource
而不是response
。
这是一个解决方案(适用于 Angular 1.4):
app.factory('Person', ['$resource', function($resource)
return $resource(
'api/path/:personId',
personId: '@_id',
update: method: 'PUT',
get:
method: 'GET',
isArray: false,
interceptor:
response: function(response)
var resource = response.resource;
resource.fullname = resource.name + ' ' + resource.surname;
return resource;
);
]);
【讨论】:
【参考方案2】:您可以尝试 intercepting 来自 Person 资源的响应并增加响应。像这样:
app.factory('Person', ['$resource', function($resource)
function getFullName()
return this.name + ' ' + this.surname;
;
return $resource('api/path/:personId',
personId: '@_id'
,
update:
method: 'PUT'
,
'get': method:'GET', isArray:false,interceptor:
'response': function(response)
response.fullname = getFullName; //augment the response with our function
return response;
);
]);
【讨论】:
【参考方案3】:如果您只需要派生属性进行显示,您可以创建一个显示过滤器,而不是用冗余数据加载您的模型:
app.filter('personFullName', function()
return function(person)
return person.name + " " + person.surname;
;
)
然后在你的模板中引用过滤器:
<div>
<p>person | personFullName</p>
<p>- should match -</p>
<p>person.name person.surname</p>
</div>
【讨论】:
这个解决方案很有趣,但我想我更愿意将虚拟属性保留在模型中,这样我就可以在多个视图中访问它,而不必处理每个视图中的过滤器。 【参考方案4】:根据文档,$resource
返回一个构造函数。您可以利用构造函数的常用prototype
添加成员,即:
var Person = $resource('api/path/:personId',
personId: '@_id'
,
update: method: 'PUT'
); // same as the 1st snippet from the question
Person.prototype.xxxx = ...;
return Person; // from your Angular service
在前面的示例中,xxxx
可以是原型中通常允许的任何内容。如果您想要的实际上是派生属性,即始终反映name
和surname
属性的JS 属性,那么您需要一个支持Object.defineProperty()
的相当新的浏览器并将上面的Person.prototype
行替换为:
Object.defineProperty(
Person.prototype,
"fullname",
get: function() return this.name + " " + this.surname;
);
【讨论】:
它像任何其他属性一样工作,但你不能为它设置值(除非你指定一个 setter) 当然不是,也不应该,因为这是一个派生(计算)的属性。如果其他用例需要,可以定义一个 setter。 我不是不同意你的观点^^,只是想澄清一下。 这看起来不错,但我想看看是否有人有更“棱角分明”的解决方案。 有角度的方法是像在那个 plunk 中所做的那样转换响应:jsfiddle.net/roadprophet/YpvG7以上是关于ngResource 中的虚拟属性的主要内容,如果未能解决你的问题,请参考以下文章
使用 ngResource 在 AngularJS 中设置 enctype
Angularjs ngResource 需要将文件作为字段之一
与 ngResource 相比,使用 Restangular 有啥优势?