我真的很喜欢干净(我认为很容易理解)的方式,承诺是自动包裹的:
$scope.myData = DataService.query({something:"etc"}); // done;
我真的不关心现在这样做的标准方法,而不是自动解包:
DataService.query({something:"etc"}).$promise.then(function (data){
$scope.myData = data;
});
我希望看到的是这样的:
$scope.pulseData = $scope.setPromise(CitsciAnalytics.pulse({
projId:"yardmap"
}));
但我无法看到如何实现这一目标。我得到的最接近的是:
$scope.pulseData = $scope.setPromise("pulseData", CitsciAnalytics.pulse({
projId:"yardmap"
}));
使用添加到根范围的函数:
.run(["$rootScope", "$log", function ($rootScope, $log) {
//parent method to avoid promise unwrapping boilerplate
$rootScope.setPromise = function (scopeVar, promise) {
if (arguments.length === 2 && promise && promise.$promise) {
var scope = this;
promise.$promise.then(function (data){
scope[scopeVar] = data;
});
} else {
$log.error("$rootScope.setPromise has invalid arguments");
}
};
}]);
但我不喜欢unDRY要求必须将范围变量名称作为附加字符串传递。有没有其他人解决这个问题,或者看到一种方法更干净地做到这一点?
答案 0 :(得分:10)
首先,您不需要使用
DataService.query({something:"etc"}).$promise.then(function(data){
$scope.myData = data;
});
明确指代$resource
,因为$resource
将返回一个空数组或对象,并在数据到达时填充它。
因此,使用$resource
类,您仍然可以使用
$scope.myData = DetaService.query(...);
$resource
的范例也是在您自己的“数据获取”服务中遵循的一种好方法:返回并清空数组,并在数据到达时填充数据。
E.g:
.factory('DataService', function ($http) {
function query(params) {
var data = [];
$http.get('/some/url/with/params').then(function (response) {
response.data.forEach(function (item) {
data.push(item);
});
});
return data;
}
return {
query: query
};
});
.controller('someCtrl', function ($scope, DataService) {
$scope.data = DataService.query({...});
如果您必须使用返回承诺的第三方服务,您可以实现您的通用功能以提供类似的功能:
.run(function ($rootScope) {
$rootScope.promiseToArray = function (promise) {
var arr = [];
promise.then(function (data) {
data.forEach(function (item) {
arr.push(item);
});
});
return arr;
};
});
.controller('someCtrl', function ($scope, ThirdPartyService) {
$scope.data = $scope.promiseToArray(ThirdPartyService.fetchData());
});
另请参阅此 short demo 。
<子> 以上示例仅用于说明目的,而非生产就绪代码 我是一个真实的应用程序,你需要优雅地处理异常,拒绝等。 子>
答案 1 :(得分:0)
如果我们真的想通过在.config()函数中将选项设置为true,我们可以重新启用展开:
.config(function($parseProvider) {
$parseProvider.unwrapPromises(true) ;
});