angularjs $resource 类级回调,或后处理
Posted
技术标签:
【中文标题】angularjs $resource 类级回调,或后处理【英文标题】:angularjs $resource class-level callbacks, or post-processing 【发布时间】:2013-03-28 07:46:22 【问题描述】:我有一个$resource
,它的 API 总是会返回一些需要在进入表示层之前清理的数据。具体来说,它是 .NET 以可爱的'/Date(...)/'
格式返回 Date 对象。
我不想每次调用.query()
或.get()
时都编写回调。是否有某种方法可以通过在更新实例属性的 REST 方法上调用的回调来扩展资源,或者通过添加某种在日期属性更改时触发的 $watch
来扩展资源?基本上这个$resource
的每个实例都会发生一些事情。
angular.module('myAppServices', ['ngResource'])
.factory('Participant', ['$resource', function ($resource)
var res = $resource('api/url/participants/:id', id: '@id' );
// This obviously doesn't work, but something kinda like this?
res.prototype.$watch(this.FieldName, function(newVal, oldVal)
if (needsCleaning(newVal.fieldName)
this.FieldName = cleanupField(newVal);
;
);
【问题讨论】:
你可以试试这个。var participant = $resource('api/url/participants/:id', id: '@id' ); var commonCallback = function() // inside this callback, participant is the populated model, // you can use participant object to do your formatting logic. // Then, if you would like to save the participant object do //participant.$save(); Please not the $ prefixed method names that becomes available to your resources instances. res.query(commonCallback) or res.get(.., commonCallback)
【参考方案1】:
啊哈,我找到了绕过它的方法,并将它留在这里。在 1.1.2 版中,他们添加了对将所有 $http.config
选项传递给 $resource
的支持。当然,我使用的 CDN 没有足够新的 angular-resource.js 版本,但切换 CDN 解决了这个问题。
我刚刚使用transformResponse
选项在数据返回时对其进行修改。
angular.module('myAppServices', ['ngResource'])
.factory('Participant', ['$resource', '$http', function ($resource, $http)
var res = $resource('api/url/participants/:id', id: '@id' ,
save:
method: 'POST',
transformResponse: $http.defaults.transformResponse.concat([
function (data, headersGetter)
data.FieldName = yourDateParsingFunction(data.FieldName);
return data;
])
);
我只是将我的转换器添加到 $httpProvider
的 transformResponse 中,它将完成所有的反序列化等操作。
【讨论】:
谢谢,我喜欢$http.defaults.transformResponse.concat
部分。
请注意:您不能在transformResponse
内部使用AJAX请求来修改data
对象的字段
我必须在工厂函数的末尾添加一个 return 语句才能使其工作。【参考方案2】:
一种简单的方法是覆盖现有的$resource
方法,您希望自己对其进行后处理。有关示例,请参见下面的代码和 cmets。
angular.module('myAppServices', ['ngResource'])
.factory('Participant', ['$resource', function ($resource)
var res = $resource('api/url/participants/:id', id: '@id' ,
// create aliases for query and get to be used later
_query: method: 'GET', isArray: true ,
_get: method: 'GET'
);
// redefine the query method
res.query = function()
// call the original query method via the _query alias, chaining $then to facilitate
// processing the data
res._query.apply(null, arguments).$then(function(res)
var data = res.data;
// do any processing you need to do with data here
return data;
);
;
// redefine the method
res.get = function()
// call the original get method via the _get alias, chaining $then to facilitate
// processing the data
res._get.apply(null, arguments).$then(function(res)
var data = res.data;
// do any processing you need to do with data here
return data;
);
;
return res;
);
您可以通过Participant.query()
或Participant.get()
在代码中使用Participant
的相同方式使用它。您在链接的 $then 处理程序中返回的数据将用于解析 $resource
返回的承诺。
【讨论】:
感谢您的回答。我不是 100% 确定,但我认为transformResponse
可能是更简单的方法。
@c0bra,当你需要访问transformResponse
中无法访问的变量时,Intelekshual 的方式很有用
此解决方案的另一个优点是我们可以重用 $resources 中的默认方法来创建我们的自定义方法,然后轻松转换响应【参考方案3】:
我的做法是在模块中添加服务:
angular.module('keeniolab', ['ngResource']).
factory('KeenIO',function ($resource)
// factory implementation
).service('KeenModel', function (KeenIO)
var KeenSession = function ()
this.data = ;
;
KeenSession.prototype.fetch = function (query)
var self = this;
KeenIO.get(query, function (result)
self.data = result;
);
;
return new KeenSession();
);
现在您可以简单地监控集合:
$scope.$watchCollection(function ()
return KeenModel.data;
,
function (value)
// code here
);
Keen.IO Resource Factory with Service Model
【讨论】:
以上是关于angularjs $resource 类级回调,或后处理的主要内容,如果未能解决你的问题,请参考以下文章
AngularJS:使用 $resource 上传文件(解决方案)