在angularjs中解析非$q承诺后,自动应用$scope更改(触发摘要)
Automatically apply $scope changes (trigger digest) after a non-$q promise resolves in angularjs
假设您有:
function myPromise() {
// using some promise lib other than $q, like Q or bluebird
var defer = Q.defer();
defer.resolve('John');
return defer.promise;
}
然后你就有了这样的东西:
function foo() {
return myPromise().then(function (name) {
return name + ' Smith';
});
}
foo().then(function (name) {
$scope.$apply(function () { // or can use $timeout
console.log('after foo');
$scope.text = 'Hey ' + name;
});
});
有没有一种方法可以修改foo,使foo块后面的自动包装在$scope中$apply()?即我们可以只拥有:
foo().then(function (name) {
console.log('after foo');
$scope.text = 'Hey ' + name;
// $scope.$apply() is automatically called after this block is executed
});
我问这个问题的原因是,我正在开发一个API,用户将在其中进行几个foo调用,如果在foo promise解析后自动触发摘要循环,这将大大减少用户的代码。我知道我可以使用回调来实现这一点,但我希望有一种更干净的方法,只使用promise。
我的直觉是,解决方案在于将非$q承诺包装成$q承诺。。。
目前在Angular端没有办法做到这一点。从另一个方向看,Q promise库也没有为此暴露钩子。
所以,你有两个选择:
- 覆盖所有Q非角度承诺的
then
方法,这将起作用,因为Q是如何结构的,但有点风险,并且可能在未来版本的Q中中断(所以在升级时要小心) - 使用像Bluebird这样的promise库,它可以让你像想要的那样无缝地使用Angular,而不会出现任何短片段问题。对于Bluebird,这个问题要简单得多
我强烈建议执行后者,并使用promise库来设置调度程序。它有更好的支持,不会产生过度的承诺。然而,如果你想使用第一个,这里是如何:
var oldThen = Q.Promise.prototype.then; // reference `then`
Q.Promise.prototype.then = function(){
return oldThen.apply(this, arguments). // decorate
then(function(value){
$rootScope.$evalAsync(function(){}); // schedule digest
return value; // keep value
},function(err){
$rootScope.$evalAsync(function(){}); // schedule digest
return $q.reject(err); // keep rejection
});
};
基本上,如果每个Q在完成后没有安排,我们会在这里安排一个摘要。关于为什么这样做,你可以阅读这个问题和答案。
(信用通知-我从我参与的一次讨论中获得了上面的代码。上面的大部分代码都是我写的,但也有一些是Angular的Jeff Cross写的,所以也要归功于他)
我只需将API函数包装在$timeout块中,就可以触发摘要循环,例如
function foo() {
return $timeout(function () {
return myPromise().then(function (name) {
return name + ' Smith';
});
});
}
相关文章:
- 正在获取Angular以检测$scope中的更改
- setInterval函数不会更改视图中的$scope
- Angular:如何在状态更改时调用scope方法
- $scope变量发生更改时未触发Angular$watch
- 将Scope变量作为指针发送,并在控制器外部对其进行更改
- 函数中的$scope变量值没有更改
- ng单击触发函数,但无法更改$scope.var
- 角度:当输入更改时更新视图 + .this/$scope
- AngularJS中存在与$scope变量相关的问题.UI中的值未更改
- Angular:$scope有效,但“;控制器为“;不触发ng更改事件
- 为什么onChange回调中对$scope.data的更改不会重新绘制chart.js
- Angular js,$scope的更改没有反映在视图中
- 强制DOM在$scope模型对工厂模型的引用发生更改时进行渲染
- 在 AngularJS 中更改$scope变量中文本的字体颜色
- 根据屏幕大小更改$scope变量
- $watch-方法不会更改scope变量
- 如何在ng-repeat中更改$scope值
- AngularJs的ng-repeat没有在更改$scope变量后更新
- 角度 - 如何通过$scope中的函数更改$scope属性值
- ng-单击值更改 + $scope.watch 绑定无法正常工作