深入理解$watch ,$apply 和 $digest --- 理解数据绑定过程——续
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;
});
它将foo
和bar
从controller里绑定到一个list里面,每次点击这个元素的时候,foo
和bar
都会自增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 --- 理解数据绑定过程——续的更多相关文章
- 理解$watch ,$apply 和 $digest --- 理解数据绑定过程
原文地址:http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/ 注 这篇博文主要是写给新手的,是给那些刚刚开始 ...
- 深入理解angularjs $watch ,$apply 和 $digest --- 理解数据绑定过程
转自:http://www.angularjs.cn/A0a6 Angular用户都想知道数据绑定是怎么实现的.你可能会看到各种各样的词汇:$watch,$apply,$digest,dirty-ch ...
- [转]理解$watch ,$apply 和 $digest --- 理解数据绑定过程
原文地址:http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/ 注 这篇博文主要是写给新手的,是给那些刚刚开始 ...
- 理解Angular中的$apply()以及$digest()
$apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...
- 深入理解Angular中的$Apply()以及$Digest()
$apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...
- (网页)理解Angular中的$apply()以及$digest()
转自CSDN: 工作有问题上CSDN上转转. $apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$ ...
- (转) 理解Angular中的$apply()以及$digest()
原文地址:http://blog.csdn.net/dm_vincent/article/details/38705099 $apply()和$digest()在AngularJS中是两个核心概念,但 ...
- 通俗理解angularjs中的$apply,$digest,$watch
<!DOCTYPE html> <html lang="zh-CN" ng-app="app"> <head> <me ...
- call,apply,bind的理解
2020-03-19 call,apply,bind的理解 先说区别call, apply基本上没什么不一样,唯一不一样的地方是传参方式不同 但是bind和call,apply有区别.bind是重新绑 ...
随机推荐
- spring mybatis 3.2调用mysql存储过程返回多结果集(完整、亲测、可用)
最近,有个开发提了个需求,希望中间件支持调用mysql存储过程时支持多结果集返回,因为某些原因我们使用了不少的存储过程,很多复杂的逻辑目前来看交互非常的多,所以从当前的现状来说,这个需求还是蛮合理的. ...
- 20145321 《网络对抗》 Web基础
20145321 <网络对抗> Web基础 基础问题回答 (1)什么是表单 表单在网页中主要负责数据采集功能,一个表单有三个基本组成部分:表单标签——这里面包含了处理表单数据所用CGI程序 ...
- vim常用的配置
.vimrc配置 syntax enable syntax on set relativenumber set autoindent set tabstop=4 set expandtab " ...
- MAKEFILE 编程基础之一【转】
本文转载自:http://www.himigame.com/gcc-makefile/766.html 概述: 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Wind ...
- Git 基础 —— 安装 配置 别名 对象
Git 基础学习系列 Git 基础 -- 安装 配置 别名 对象 Git 基础 -- 常用命令 Git 基础 -- 常见使用场景 Git基础 -- Github 的使用 Git 安装 Git下载地址 ...
- bootstrap3
bs是基于html5和css3的, h5和css3是今后的趋势. html5只是说文档的 "标准"是h5, 但是文档的类型仍然是 html. 所以在写文档类型的时候, 就不能要那个 ...
- [luogu 3957]跳房子
题目链接 50分做法 挺显然的一个做法,因为金币量是单调的(如果你花i枚金币可以得到最优解,i+1枚也一定可以),所以可以二分答案 然后对于二分出来的每个答案,都做一遍dp,效率$O(n^2logn) ...
- chromedriver下载安装
博主开发平台是win10,Python版本是3.6.最近需要用到chromedriver+selenium,下载好selenium后,pip install chromedriver,直接安装到pyt ...
- Android本地广播
Android中使用的广播一般是系统全局广播,即发出的广播可以被其他任何应用程序接收到,并且我们也可以接收来自于其他任何应用程序的广播.这样就很容易会引起安全性的问题,比如说我们发送的一些携带关键性数 ...
- API接口自动化之2 处理http请求的返回体,对返回体做校验
举例一个接口测试的常见流程 1) 发送接口请求2) 断言接口响应状态是不是200 OK3) 断言接口的响应时间低于某一个值(看情况,不是必选)4) 断言响应数据是否正确,一般的做法是判断某一个值是否相 ...