185

我有一个在我的自定义指令范围之外发生的单击事件,因此我没有使用“ng-click”属性,而是使用 jQuery.click() 侦听器并在我的范围内调用一个函数,如下所示:

$('html').click(function(e) {
  scope.close();
);

close() 是一个简单的函数,如下所示:

scope.close = function() {
  scope.isOpen = false;
}

在我看来,我有一个绑定到 isOpen 的“ng-show”元素,如下所示:

<div ng-show="isOpen">My Div</div>

调试时,我发现 close() 被调用,isOpen 被更新为 false,但 AngularJS 视图没有更新。有没有办法手动告诉 Angular 更新视图?或者是否有更“角度”的方法来解决我没有看到的这个问题?

4

4 回答 4

335

解决办法是打电话...

$scope.$apply();

...在我的 jQuery 事件回调中。

于 2012-09-06T17:09:55.387 回答
39

为什么$apply要调用?

TL;DR: 只要你想应用在Angular 世界之外$apply所做的更改,就应该调用它。


只是为了更新@Dustin 的答案,这里解释 $apply究竟做了什么以及它为什么起作用。

$apply()用于从 AngularJS 框架之外执行 AngularJS 中的表达式。(例如来自浏览器 DOM 事件、setTimeout、XHR 或第三方库)。因为我们正在调用 AngularJS 框架,所以我们需要执行适当的 异常处理范围生命周期,执行 watch

Angular 允许将任何值用作绑定目标。然后在任何 JavaScript 代码循环结束时,它会检查值是否已更改。检查任何绑定值是否已更改的步骤实际上有一个方法$scope.$digest()1。我们几乎从不直接调用它,而是使用$scope.$apply()它(它将调用$scope.$digest)。

Angular 仅监视表达式中使用的变量以及$watch范围内的任何内容。因此,如果您在 Angular 上下文之外更改模型,则需要调用$scope.$apply()传播这些更改,否则 Angular 将不知道它们已更改,因此绑定不会更新2

于 2017-04-24T14:58:12.240 回答
17

利用

$route.reload();

记得注入$route你的控制器。

于 2016-09-19T09:35:38.533 回答
1

虽然以下内容对我有用:

$scope.$apply();

它需要更多的设置和两者的使用.$on.$broadcast工作或潜在地$.watch

但是,以下需要的代码要少得多,而且工作起来很吸引人。

$timeout(function() {});

在更新范围变量后立即添加超时允许 AngularJS 意识到有更新并自行应用它。

于 2022-01-04T18:23:20.550 回答