当使用超时调用时,角度双向绑定不起作用

时间:2016-01-19 14:28:48

标签: javascript jquery angularjs html5 underscore.js

所以我有一个HTML模板,其中我有以下角度表达式ThisDocument。存储在范围对象中的播放器的初始分数在表达式的位置正确呈现。

现在,我点击了一个按钮,需要更新此分数。如果我使用硬编码值简单更新玩家得分,它可以正常工作:

{{player.score}}

但我的问题是我的玩家得分是一个复杂的计算,需要我使用$scope.updateScore = function (){ $scope.player.score = 1000; //this is updated without any issues }; 。因此,当我在_.defer内包装我的早期代码(用于测试)时,它不起作用:

_.defer

我理解 $scope.updateScore = function (){ _.defer(function() { $scope.player.score = 5000; //this is not updated... }); }; 的方式只是强调了_.defer的包装。我希望在setTimeout使用任何延迟后,当它最终更新得分时,由于Angular双向绑定,它将反映在HTML中。

但只有在使用_.defer时才会发生这种情况,否则它会按预期工作。另外_.defer正在更新Angular对象,因为如果我在延迟代码中执行_.defer,那么在控制台中几秒钟之后我会看到更新分数(5000)。

任何角度/ Javascript专家都可以帮助我理解我做错了什么以及如何解决它。请注意,由于各种技术/遗留原因,删除console.log(player.score)并非真正的选项。

我只想弄清楚为什么当对象以延迟方式更新时,Angular不会更新视图。

非常感谢任何指针。

2 个答案:

答案 0 :(得分:2)

Angular没有"知道"关于这个延迟,所以即使值得到更新,它也不会出现在视图中直到下一个摘要循环。 您可以将$timeout注入控制器并使用它:

_.defer(function() {
     $timeout(function() {
          $scope.player.score = 5000; //this is not updated...
     });
});

您还应该阅读角度(https://docs.angularjs.org/api/ng/service/ $ q)

中的延迟对象

答案 1 :(得分:1)

_.defer将代码排除在角度摘要的范围之外,因为它在内部调用setTimeout

您需要在延迟函数内手动启动摘要,以便使用$scope.$apply在该点进行角度重新绑定:

$scope.updateScore = function (){
     _.defer(function() {
          player.score = 5000;
          $scope.$apply();
     });
};

或者您需要将回调保留在角度范围内,可能是使用$timeout(但请记住将$timeout注入您的控制器/指令中):

$scope.updateScore = function (){
     $timeout(function() {
          player.score = 5000;
     }, 1); // or 0, but _.defer passes 1
};

我会选择偏好的选项2,我个人无法看到如何使用_.defer,但当然这取决于你。