$scope.$watch 没有调用,但$digest已经在进行中

$scope.$watch not called, but $digest already in progress

本文关键字:digest 进行中 scope watch 调用      更新时间:2023-09-26

我在调用检索数据模型后未评估$scope.$watch的问题。我会解释一下,但对于不耐烦的人来说,也许你可以根据这个小提琴弄清楚发生了什么:http://jsfiddle.net/ADukg/3964/。

在我们的 Angular 项目中,我们让一些指令构建自己的数据模型,这些数据模型有时也会传递给其他包含的指令。在这种情况下,构建自己的模型的指令是myMessages的,并且其数据传递到的指令是myObjects的。

myMessages 指令依赖于一个名为 messageManager 的服务来随时获取与其相关的消息(在我们的代码中,这是基于$routeParams值之类的东西,例如 http://localhost/messages/34 )。对于我的示例,我只是忽略了参数并直接传回了数据。

有趣的是,如果我注释掉第 55 行和第 68 行(包装setTimeout调用),这段代码工作"很好"(我把它放在引号里,因为,好吧,我真的不确定它是否真的使用了良好的实践)。但是,保留调用以模拟 HTTP 请求,myObjects 指令的 link 方法中的 objects scope 变量的值为空,并且针对该变量设置的监视在 2 秒后无法运行。

我试图通过在调用 ctrl.loadData() 和实际loadData方法中显式调用$scope.$apply来欺骗手表重新评估,但收到此错误:

$digest已经在进行

浏览文档,这似乎是正确的,因为当我们进行这些调用时,我们仍然在 Angular 上下文中(我们在服务中使用 ngResource,所以它不会调用一些 jQuery 上下文或任何奇怪的内容)。无论我尝试什么(包括将第三个参数设置为 $scope.$watch 函数以true),我似乎都无法在填充数据后重新评估针对 objects 变量的手表。

任何帮助将不胜感激。

应使用 $timeout 而不是 setTimeout $timeout因为这将触发摘要循环以使数据在绑定中可用。

myApp.factory('messageManager', function ($q, $timeout) {
    return {
        getMessages: function () {
            var deferred, promise;
            deferred = $q.defer();
            promise = deferred.promise;
            $timeout(function () {
                deferred.resolve({
                    messages: [{
                        firstName: 'Sam',
                        lastName: 'Rockwell',
                    }, {
                        firstName: 'Nat',
                        lastName: 'Faxon',
                    }, {
                        firstName: 'Jim',
                        lastName: 'Rash'
                    }]
                });
            }, 2000);
            return promise;
        }
    };
});