浅谈Angular 的变化检测的方法


Posted in Javascript onMarch 01, 2018

Change Detection (变化检测) 是 Angular 2 中最重要的一个特性。当组件中的数据发生变化的时候,Angular 2 能检测到数据变化并自动刷新视图反映出相应的变化。

在介绍变化检测之前,我们要先介绍一下浏览器中渲染的概念,渲染是将模型映射到视图的过程。模型的值可以是 JavaScript 中的原始数据类型、对象、数组或其他数据对象。然而视图可以是页面中的段落、表单、按钮等其他元素,这些页面元素内部使用 DOM(Document Object Model) 来表示,为了更好地理解,我们来看一个具体的示例:

<h4 id="greeting"></h4> <script> document.getElementById("greeting").innerHTML = "Hello World!"; </script>

这个例子很简单,因为模型不会变化,所以页面只会渲染一次。如果数据模型在运行时会不断变化,那么整个过程将变得复杂。因此为了保证数据与视图的同步,页面将会进行多次渲染。接下来我们来考虑一下以下几个问题:

1、什么时候模型会发生变化

2、模型产生了什么变化

3、变化后需要更新的视图区域在哪里

4、怎么更新对应视图区域

而变化检测的基本目的就是解决上述问题。在 Angular 2 中当组件内的模型发生变化的时候,组件内的变化检测器就会检测到更新,然后通知视图刷新。因此变化检测器有两个主要的任务:

1、检测模型的变化

2、通知视图刷新

接下来我们来分析一下什么是变化,变化是怎么产生的。

变化和事件

变化是旧模型与新模型之间的区别,换句话说变化产生了一个新的模型。让我们来看一下下面的代码:

import { Component } from '@angular/core'; @Component({
 selector: 'exe-counter',
 template: `
 <p>当前值:{{ counter }}</p>
 <button (click)="countUp()"> + </button>` }) export class CounterComponent {
 counter = 0;

 countUp() { this.counter++;
 }
}

页面首次渲染完后,计数器的当前值为0。当我们点击 + 按钮时,计数器的 counter 值将会自动加1,之后页面中当前值也会被更新。在这个例子中,点击事件引起了 counter 属性值的变化。

我们继续看下一个例子:

import { Component, OnInit } from '@angular/core'; @Component({
 selector: 'exe-counter',
 template: `
  <p>当前值:{{ counter }}</p>
 ` }) export class CounterComponent implements OnInit {
 counter = 0;
 ngOnInit() {
  setInterval(() => { this.counter++;
  }, 1000);
 }
}

该组件通过 setInterval 定时器,实现每秒钟 counter 值自动加1。在这种情况下,它是定时器事件引起了属性值的变化。最后我们再来看个例子:

import { Component, OnInit } from '@angular/core'; import { Http } from '@angular/http'; @Component({
 selector: 'exe-counter',
 template: `
  <p>当前值:{{ counter }}</p>
 ` }) export class CounterComponent implements OnInit {
 counter = 0; constructor(private http: Http) {}
 ngOnInit() { this.http.get('/counter-data.json')
    .map(res => res.json())
    .subscribe(data => { this.counter = data.value;
    });
 }
}

该组件在进行初始化的时候,会发送一个 HTTP 请求去获取初始值。当请求成功返回的时候,组件的 counter 属性的值会被更新。在这种情况下,它是由 XHR 回调引起了属性值的变化。

现在我们来总结一下,引起模型变化的三类事件源:

1、Events:click, mouseover, keyup ...

2、Timers:setInterval、setTimeout

3、XHRs:Ajax(GET、POST ...)

这些事件源有一个共同的特性,即它们都是异步操作。那我们可以这样认为,所有的异步操作都有可能会引起模型的变化。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
CSS+Table图文混排中实现文本自适应图片宽度(超简单+跨所有浏览器)
Feb 14 Javascript
JQuery 学习笔记 选择器之六
Jul 23 Javascript
javascript学习笔记(六) Date 日期类型
Jun 19 Javascript
js(JavaScript)实现TAB标签切换效果的简单实例
Feb 26 Javascript
javascript学习总结之js使用技巧
Sep 02 Javascript
AngularJS 指令详细介绍
Jul 27 Javascript
IScroll5实现下拉刷新上拉加载的功能实例
Aug 11 Javascript
vue组件实现文字居中对齐的方法
Aug 23 Javascript
通过一个简单的例子学会vuex与模块化
Nov 22 Javascript
详解@angular/cli 改变默认启动端口两种方式
Nov 29 Javascript
javascript的惯性运动实现代码实例
Sep 07 Javascript
js实现倒计时秒杀效果
Mar 25 Javascript
ES6学习笔记之map、set与数组、对象的对比
Mar 01 #Javascript
Node.js静态服务器的实现方法
Feb 28 #Javascript
JS脚本加载后执行相应回调函数的操作方法
Feb 28 #Javascript
vue+webpack 打包文件 404 页面空白的解决方法
Feb 28 #Javascript
webpack项目调试以及独立打包配置文件的方法
Feb 28 #Javascript
vue-cli+webpack项目 修改项目名称的方法
Feb 28 #Javascript
vue 组件 全局注册和局部注册的实现
Feb 28 #Javascript
You might like
PHP包含文件函数include、include_once、require、require_once区别总结
2014/04/05 PHP
mac环境中使用brew安装php5.5.15
2014/08/18 PHP
Laravel框架数据库CURD操作、连贯操作总结
2014/09/03 PHP
smarty内置函数config_load用法实例
2015/01/22 PHP
非常有用的9个PHP代码片段
2016/04/06 PHP
Yii+MYSQL锁表防止并发情况下重复数据的方法
2016/07/14 PHP
PHP中strtr与str_replace函数运行性能简单测试示例
2019/06/22 PHP
document.getElementById介绍
2011/09/13 Javascript
js禁止页面使用右键(简单示例代码)
2013/11/13 Javascript
javascript中DOM复选框选择用法实例
2015/05/14 Javascript
jQuery实现可用于博客的动态滑动菜单完整实例
2015/09/17 Javascript
jquery UI Datepicker时间控件的使用方法(基础版)
2015/11/07 Javascript
Jquery AJAX POST与GET之间的区别详细介绍
2016/10/17 Javascript
bootstrap常用组件之头部导航实现代码
2017/04/20 Javascript
AngularJS 表单验证手机号的实例(非必填)
2017/11/12 Javascript
vue.js中proxyTable 转发请求的实现方法
2018/09/20 Javascript
Vue resource三种请求格式和万能测试地址
2018/09/26 Javascript
详解vue 不同环境配置不同的打包命令
2019/04/07 Javascript
使用Vue.observable()进行状态管理的实例代码详解
2019/05/26 Javascript
[02:17]TI4西雅图DOTA2前线报道 啸天mik夫妻档解说
2014/07/08 DOTA
Python爬虫使用浏览器cookies:browsercookie过程解析
2019/10/22 Python
python实现的读取网页并分词功能示例
2019/10/29 Python
浅谈cv2.imread()和keras.preprocessing中的image.load_img()区别
2020/06/12 Python
Pycharm安装第三方库失败解决方案
2020/11/17 Python
美国维生素、补充剂、保健食品购物网站:Vitacost
2016/08/05 全球购物
C++:局部变量能否和全局变量重名
2014/03/03 面试题
电子商务应届生求职信
2013/11/16 职场文书
党的群众路线教育实践活动动员会主持词
2014/03/20 职场文书
动物科学专业求职信
2014/07/27 职场文书
自动化专业大学生职业生涯规划范文:爱拚才会赢
2014/09/12 职场文书
党员学习群众路线教育实践活动对照检查材料
2014/09/23 职场文书
校车安全管理责任书
2015/05/11 职场文书
食品安全主题班会
2015/08/13 职场文书
AJAX引擎原理以及XmlHttpRequest对象的axios、fetch区别详解
2022/04/09 Javascript
Java 使用类型为Object的变量指向任意类型的对象
2022/04/13 Java/Android
MySQL 自动填充 create_time 和 update_time
2022/05/20 MySQL