简体   繁体   English

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

[英]angular two-way binding not working when called with a timeout

So I have an HTML template inside which I have following angular expression {{player.score}} . 所以我有一个HTML模板,其中我有以下角度表达式{{player.score}} The initial score of the player that is stored in a scope object is correctly rendered in the place of the expression. 存储在范围对象中的播放器的初始分数在表达式的位置正确呈现。

Now, I have a button click on which this score needs to be updated. 现在,我点击了一个按钮,需要更新此分数。 If I simple update the players score with a hardcoded value it works correctly: 如果我使用硬编码值简单更新玩家得分,它可以正常工作:

$scope.updateScore = function (){
     $scope.player.score = 1000; //this is updated without any issues
};

But my problem is that my player score is a complicated calculation, which needs me to use _.defer . 但我的问题是我的玩家得分是一个复杂的计算,需要我使用_.defer So when I wrap my earlier code (for testing) inside _.defer it does not work: 因此,当我在_.defer包装我的早期代码(用于测试)时,它不起作用:

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

The way I understand _.defer it is just underscores wrapper for setTimeout . 我理解_.defer的方式只是强调了setTimeout包装。 I would expect that after whatever delay _.defer uses, when it finally gets around to updating the score, then it will get reflected in the HTML due to the Angular two-way binding. 我希望在_.defer使用的任何延迟_.defer ,当它最终更新得分时,由于Angular双向绑定,它将反映在HTML中。

But this is not happening only when _.defer is used, else it works as expected. 但是只有在使用_.defer_.defer发生这种情况,否则它会按预期工作。 Also _.defer is updating the Angular object because if I do a console.log(player.score) in the deferred code, then after a few seconds in the console I do see the update score (5000). 另外_.defer正在更新Angular对象,因为如果我在延迟代码中执行console.log(player.score) ,那么在控制台中几秒后我会看到更新分数(5000)。

Can any angular/Javascript experts help me understand what I am doing incorrect and how I can fix it. 任何有角度/ Javascript专家都可以帮助我理解我做错了什么以及如何解决它。 Please note that removing _.defer is not really an option because of various technical/legacy reasons. 请注意,由于各种技术/遗留原因,删除_.defer并不是一个真正的选择。

I am just trying to figure out why when the object is updated in a deferred manner, the Angular does not update the view. 我只想弄清楚为什么当对象以延迟方式更新时,Angular不会更新视图。

Any pointers are greatly appreciated. 任何指针都非常感谢。

Angular doesn't "know" about this defer so even if the value gets updated, it won't appear in the view until the next digest loop. Angular不会“知道”这个延迟,因此即使值更新,它也不会出现在视图中,直到下一个摘要循环。 You can inject $timeout to your controller and use it like this: 您可以向控制器注入$ timeout并像这样使用它:

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

You should also read about deferred objects in angular ( https://docs.angularjs.org/api/ng/service/ $q) 您还应该阅读有关角度的延迟对象( https://docs.angularjs.org/api/ng/service/ $ q)

_.defer takes the code out of the scope of the angular digest, because it internally calls setTimeout . _.defer将代码从角度摘要的范围中取出,因为它在内部调用setTimeout

You either need to manually kick off a digest inside the deferred function so angular rebinds at that point, using $scope.$apply : 您需要手动启动延迟函数内的摘要,以便在该点使用$ scope重新绑定。$ apply

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

or you need to keep the callback inside the angular scope, probably by using $timeout (but remember to inject $timeout into your controller/directive): 或者您需要将回调保留在角度范围内,可能是使用$timeout (但记得在控制器/指令中注入$timeout ):

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

I would go with option 2 from preference, and I personally can't see how using _.defer can be required over this, but of course it is up to you. 我会选择优先选项2,我个人无法看到如何使用_.defer ,但当然这取决于你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM