所以我有一个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不会更新视图。
非常感谢任何指针。
答案 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
,但当然这取决于你。