【问题标题】:Angular $scope won't update in bootbox callbackAngular $scope 不会在 bootbox 回调中更新
【发布时间】:2016-03-19 10:03:57
【问题描述】:

这是我关于 SO 的第一个问题。

当我在作用域上拼接一个数组元素时,在 bootbox.js 的回调中完成时,该更改不会反映。

作品:

$scope.deleteA = function() {
    if (confirm("Really delete Item 3?")) {
      $scope.itemsA.splice(2, 1);
    }
}

不起作用:

$scope.deleteB = function() {
    bootbox.confirm("Really delete Item 3?", function(answer) {
      if (answer === true) {
        $scope.itemsB.splice(2, 1);
      }
    });
}

我主要想了解为什么。这对我来说比有一个花哨的解决方法重要得多。

I created a Plunker to show the effect

【问题讨论】:

  • 在引导箱回调角度不知道有什么变化,这就是为什么不更新视图
  • 考虑使用 ng-boot-box,一个用于 Bootbox.js 的 AngularJS 包装器

标签: javascript angularjs angularjs-scope bootbox ng-boot-box


【解决方案1】:

任何变化都发生在来自 Angular 外部世界的 Angular 范围变量上,不会让 Angular 摘要系统运行摘要循环以更新绑定。
bootbox 回调角度不知道有什么变化,这就是为什么不更新视图。
要解决此问题,您需要使用$apply method$timeout service 手动启动摘要循环,如下所示

bootbox.confirm("Really delete Item 3?", function(answer) {
  if (answer === true) {
    $scope.$apply(function(){
        $scope.itemsB.splice(2, 1);
    });
  }
});

【讨论】:

  • 你好@Grundy。谢谢您的回答。我明白了,这个解决方案有效,但我仍然不明白为什么 angular 会“看到”所做的更改,当它们在范围函数中完成时,但在函数中完成时看不到它们,也在作用域函数中定义。 Angular 的世界在哪里停止,为什么?
  • @DannySoul,因为在每个用户事件上,例如 clickchangekeyup 等,角度运行摘要循环会自动循环,并在需要时更新视图,在您的情况下 - 角度不运行这个在 bootbox 回调之后,你应该手动运行它
  • @Grundy,再次感谢您的回答。但我还是不太明白。假设$scope.name 是一个包含名称的字符串。众所周知,有角。如果我从函数$scope.myFunction 中更改$scope.name 的值,它会反映在视图中。如果我在$scope.myFunction(例如setTimeout)内部定义的函数中更改值,则不会反映。为什么角度能够在一种情况下看到它,而在另一种情况下却看不到。为什么调用函数很重要?
  • @DannySoul,尝试阅读更多关于 HTML Compilerangular scope life cycle 的信息
【解决方案2】:

应用范围更改的安全方法是使用$timeout 服务。

bootbox.confirm("Really delete Item 3?", function(answer) {
  if (answer === true) {
    $timeout($scope.itemsB.splice(2, 1));
  }
});

因此您无需担心$digest 阶段,您的$apply 将是一个高调用堆栈,请查看AngularJS Wiki - Anti-Patterns 点-2。

不要做if (!$scope.$$phase) $scope.$apply(),这意味着你的 $scope.$apply() 在调用堆栈中不够高。

【讨论】:

  • $timeout 的使用是code smell,这是更深层次问题的症状。请记住,在大多数地方(控制器、服务)$apply 已经被处理事件的指令调用。只有在实现自定义事件回调或使用第三方库回调时,才需要显式调用 $apply
猜你喜欢
  • 2017-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
相关资源
最近更新 更多