【问题标题】:angular two-way binding not working when called with a timeout超时调用时,角度双向绑定不起作用
【发布时间】:2016-01-19 22:39:36
【问题描述】:

所以我有一个 HTML 模板,里面有下面的角度表达式 {{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 的下划线包装。我希望在 _.defer 使用任何延迟之后,当它最终可以更新分数时,由于 Angular 双向绑定,它将反映在 HTML 中。

但这不会仅在使用 _.defer 时发生,否则它会按预期工作。 _.defer 也在更新 Angular 对象,因为如果我在延迟代码中执行 console.log(player.score),那么在控制台中几秒钟后,我确实会看到更新分数(5000)。

任何角度/Javascript 专家都可以帮助我了解我做错了什么以及如何解决它。请注意,由于各种技术/遗留原因,删除 _.defer 并不是一个真正的选择。

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

非常感谢任何指针。

【问题讨论】:

  • 不应该是player.score$scope.player.score吗?
  • 是的 - player.scope 是一个错字。
  • _.defer() 不会触发摘要循环。在为您的范围分配新内容后,您应该“手动”执行此操作。或者,您也可以使用$timeout,无论如何都会这样做。
  • @GuidoKitzing:你能给我举个例子,说明在我的特定用例中如何做到这一点吗?非常感谢
  • _.defer()分配后尝试使用$scope.$apply()

标签: javascript jquery angularjs html underscore.js


【解决方案1】:

Angular 并不“知道”这个延迟,所以即使值被更新,它也不会出现在视图中,直到下一个摘要循环。 您可以将$timeout 注入您的控制器并像这样使用它:

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

您还应该阅读有关 Angular 中的延迟对象 (https://docs.angularjs.org/api/ng/service/$q)

【讨论】:

    【解决方案2】:

    _.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,但当然这取决于你。

    【讨论】:

      猜你喜欢
      • 2012-02-14
      • 1970-01-01
      • 2017-10-20
      • 2014-06-26
      • 2014-04-10
      • 2011-10-14
      • 2014-03-12
      相关资源
      最近更新 更多