Angular什么时候不会自动为我们$apply呢?

这是Angular新手共同的痛处。为什么我的jQuery不会更新我绑定的东西呢?因为jQuery没有调用$apply,事件没有进入angular context$digest循环永远没有执行。

我们来看一个有趣的例子:

假设我们有下面这个directive和controller

app.js

app.directive('clickable', function() {

return {
restrict: "E",
scope: {
foo: '=',
bar: '='
},
template: '<ul style="<li>{{foo}}</li><li>{{bar}}</li></ul>',
link: function(scope, element, attrs) {
element.bind('click', function() {
scope.foo++;
scope.bar++;
});
}
} }); app.controller('MainCtrl', function($scope) {
$scope.foo = 0;
$scope.bar = 0;
});

它将foobar从controller里绑定到一个list里面,每次点击这个元素的时候,foobar都会自增1。

那我们点击元素的时候会发生什么呢?我们能看到更新吗?答案是否定的。因为点击事件是一个没有封装到$apply里面的常见的事件,这意味着我们会失去我们的计数吗?不会

真正的结果是:$scope确实改变了,但是没有强制$digest循环,监视foo 和bar$watch没有执行。也就是说如果我们自己执行一次$apply那么这些$watch就会看见这些变化,然后根据需要更新DOM。现在你在想那并不是你想要的,你想要的是点击蓝色区域的时候就更新点击数。很简单,执行一下$apply就可以了:

element.bind('click', function() {
scope.foo++;
scope.bar++;
scope.$apply();
});

$apply是我们的$scope(或者是direcvie里的link函数中的scope)的一个函数,调用它会强制一次$digest循环(除非当前正在执行循环,这种情况下会抛出一个异常,这是我们不需要在那里执行$apply的标志)。

有用啦!但是有一种更好的使用$apply的方法:

element.bind('click', function() {
scope.$apply(function() {
scope.foo++;
scope.bar++;
});
})

因此,如果你想使用一个jQuery插件,并且要执行$digest循环来更新你的DOM的话,要确保你调用了$apply

使用$watch来监视你自己的东西

你已经知道了我们设置的任何绑定都有一个它自己的$watch,当需要时更新DOM,但是我们如果要自定义自己的watches呢?简单

app.js

app.controller('MainCtrl', function($scope) {
$scope.name = "Angular"; $scope.updated = 0; $scope.$watch('name', function(newValue, oldValue) {
if (newValue === oldValue) { return; } // AKA first run
$scope.updated++;
});
});

index.html

<body ng-controller="MainCtrl">
<input ng-model="name" />
Name updated: {{updated}} times.
</body>

watch的第二个参数接受两个参数,新值和旧值。我们可以用他们来略过第一次的执行。通常你不需要略过第一次执行,但在这个例子里面你是需要的。

总结

好吧,我希望你们已经学会了在Angular中数据绑定是如何工作的。我猜想你的第一印象是dirty-checking很慢,好吧,其实是不对的。它像闪电般快。但是,是的,如果你在一个模版里有2000-3000个watch,它会开始变慢。但是我觉得如果你达到这个数量级,就可以找个用户体验专家咨询一下了!

深入理解$watch ,$apply 和 $digest --- 理解数据绑定过程——续的更多相关文章

  1. 理解$watch ,$apply 和 $digest --- 理解数据绑定过程

    原文地址:http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/ 注 这篇博文主要是写给新手的,是给那些刚刚开始 ...

  2. 深入理解angularjs $watch ,$apply 和 $digest --- 理解数据绑定过程

    转自:http://www.angularjs.cn/A0a6 Angular用户都想知道数据绑定是怎么实现的.你可能会看到各种各样的词汇:$watch,$apply,$digest,dirty-ch ...

  3. [转]理解$watch ,$apply 和 $digest --- 理解数据绑定过程

    原文地址:http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/ 注 这篇博文主要是写给新手的,是给那些刚刚开始 ...

  4. 理解Angular中的$apply()以及$digest()

    $apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...

  5. 深入理解Angular中的$Apply()以及$Digest()

    $apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...

  6. (网页)理解Angular中的$apply()以及$digest()

    转自CSDN: 工作有问题上CSDN上转转. $apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$ ...

  7. (转) 理解Angular中的$apply()以及$digest()

    原文地址:http://blog.csdn.net/dm_vincent/article/details/38705099 $apply()和$digest()在AngularJS中是两个核心概念,但 ...

  8. 通俗理解angularjs中的$apply,$digest,$watch

    <!DOCTYPE html> <html lang="zh-CN" ng-app="app"> <head> <me ...

  9. call,apply,bind的理解

    2020-03-19 call,apply,bind的理解 先说区别call, apply基本上没什么不一样,唯一不一样的地方是传参方式不同 但是bind和call,apply有区别.bind是重新绑 ...

随机推荐

  1. maven parent工程.pom修改后未自动更新

    前两周,因为框架parent工程的pom文件做了一点变更,然后在测试服务器进行maven install的时候,死都找不到新的依赖,都把nexus翻了个遍,确定是最新的了,就是download不下来, ...

  2. 20145101《Java程序设计》第9周学习总结

    20145101<Java程序设计>第9周学习总结 教材学习内容总结 第十六章 整合数据库 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增 ...

  3. linux下有线网卡出现ADDRCONF(NETDEV_UP): eth0: link is not ready的解决方法

    一.背景 2018年5月24日,笔者的pc已经连续运转两天了,突然要使用有线网卡,却发现有线网卡无法正常工作,于是查看了一下内核日志: r8169 0000:05:00.0 eth0: link do ...

  4. luogu P2073 送花 线段树

    思路&心路 一眼认定沙比提 写的比较慢,写了1小时吧 开心的交上去 卧槽,只有20? 不服不服,拿着题解的代码去对拍 Emma,<100没问题 100000数据错了,还只是错了一个数据 ...

  5. 不同ContentType的post请求

    public static T Invoke<T>(string url, object input, bool requireJSON = true) { using (var clie ...

  6. BZOJ3300: [USACO2011 Feb]Best Parenthesis 模拟

    Description Recently, the cows have been competing with strings of balanced  parentheses and compari ...

  7. 大数字运算, BigInteger

    package com.ykmimi.test1; import java.math.BigInteger; /** * 大数字运算 * @author ukyor * */ public class ...

  8. 01_re正则表达式

    正则表达式,是一个特殊的字符串, 是对一类字符串的描述 ( 怎么描述一类字符: 普通字符+元字符+重复)检测给定的字符串,是否和正则表达式描述的字符串相匹配 举例:1) 检查一串数字是否是电话号码2) ...

  9. Quartz.NET教程:(01) 使用Quartz

    使用调度器 (scheduler) 之前要先用 ISchedulerFactory 的一个实现来实例化调度器(scheduler).一旦调度器实例化完成,则它可以被启动.置于备用模式或者关闭.需要注意 ...

  10. PCH Warning: header stop cannot be in a macro or #if block.

    在编写头文件时,遇到这么一个warning:PCH Warning: header stop cannot be in a macro or #if block. An intellisense PC ...