【发布时间】:2017-07-05 14:19:11
【问题描述】:
问题:在控制器方法中使用this.promise.then(function(){}) 函数似乎会创建一个 $rootScope:infDig 循环,尽管该方法的返回值不会改变。值得注意的是,当删除 .then() 行时,无限摘要循环消失了(参见代码)。
代码:
视图中的{{ getSelectedProjects() }} 和附加控制器中的以下方法
var vm = this;
vm.getSelectedProjects = function() {
if (angular.isUndefined(vm.hello)) {
vm.hello = "hello"
vm.promise = $q.when("hello i am a resolved promise")
}
vm.promise //In my original code, this promise is returned by a service (MyService.getPromise()). The resolved value of the returned promise may change which is why the service needs to be called at each digest cycle.
.then(function (ans) {
vm.hello = ans;
}); //remove .then(...) function and there is no infinite digest loop anymore
return vm.hello;
}
问题:尽管返回值没有改变,为什么会创建一个无限摘要循环?我怎样才能避免它(我非常需要那个承诺的结果)?。
我摇摇欲坠的想法: 我想这与 .then() 每次返回一个 new 承诺的事实有关。文档没有说明,但是如果每次都将这个承诺附加到控制器对象(vm),这可能会被视为控制器的状态更改并触发一个新的摘要循环,该循环重新评估 vm.getSelectedProjects()并再次将新的承诺附加到控制器等。
编辑 我在“摇摇欲坠的想法”中的假设似乎并不完全正确或完整,因为此代码仍然存在问题:
vm.getSelectedProjects = function() {
if (angular.isUndefined(vm.hello)) {
vm.hello = "hello"
}
$q.when("hello i am a resolved promise")//this object is not attached to the controller object
.then(function () {});
return vm.hello;
}
【问题讨论】:
-
这是您在控制台中看到的错误docs.angularjs.org/error/$rootScope/infdig 吗?
-
没错,将其添加到帖子中。
-
并且循环是通过使用一个承诺创建的,当它解决时 - 一个新的摘要循环开始并且这个函数被一次又一次地调用
-
"$q 与 AngularJS 中的 $rootScope.Scope Scope 模型观察机制集成,"解析触发新的摘要循环
-
这不是承诺。这是回调。每次执行你的函数时,它都会向 then() 传递一个新的回调,这个回调在摘要循环结束时执行,并触发一个新的回调,它重新评估方法等。只是不要调用服务和从该方法内部注册一个回调到一个承诺。这应该从事件处理程序(单击,无论如何)或您的控制器构造函数中完成。不是来自表达式评估。