浅谈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 相关文章推荐
JS 实现双色表格实现代码
Nov 24 Javascript
基于JQuery的密码强度验证代码
Mar 01 Javascript
一个可绑定数据源的jQuery数据表格插件
Jul 17 Javascript
基于javascript实现彩票随机数生成(升级版)
Apr 17 Javascript
JQuery 设置checkbox值二次无效的解决方法
Jul 22 Javascript
jQuery实现可移动选项的左右下拉列表示例
Dec 26 Javascript
微信小程序 使用腾讯地图SDK详解及实现步骤
Feb 28 Javascript
基于bootstrap实现bootstrap中文网巨幕效果
May 02 Javascript
Javascript实现页面滚动时导航智能定位
May 06 Javascript
Three.js 再探 - 写一个微信跳一跳极简版游戏
Jan 04 Javascript
Bootstrap实现的表格合并单元格示例
Feb 06 Javascript
vue3 自定义图片放大器效果的示例代码
Jul 23 Vue.js
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
PHP4实际应用经验篇(3)
2006/10/09 PHP
php开发中的页面跳转方法总结
2015/04/26 PHP
PHP 7安装使用体验之性能大提升,兼容性强,扩展支持不够(升级PHP要谨慎)
2017/07/27 PHP
JavaScript Event学习第二章 Event浏览器兼容性
2010/02/07 Javascript
仿谷歌主页js动画效果实现代码
2013/07/14 Javascript
ie8 不支持new Date(2012-11-10)问题的解决方法
2013/07/31 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
2015/03/18 Javascript
JavaScript AOP编程实例
2015/06/16 Javascript
使用jQuery mobile库检测url绝对地址和相对地址的方法
2015/12/04 Javascript
JS实现经典的中国地区三级联动下拉菜单功能实例【测试可用】
2017/06/06 Javascript
详解Angular Reactive Form 表单验证
2017/07/06 Javascript
浅谈pc端rem字体设置的问题
2017/08/03 Javascript
浅析Node.js非对称加密方法
2018/01/29 Javascript
Vue-Router2.X多种路由实现方式总结
2018/02/09 Javascript
vue 表单验证按钮事件交由父组件触发的方法
2018/12/17 Javascript
JS中实现一个下载进度条及播放进度条的代码
2019/06/10 Javascript
js获取浏览器地址(获取第1个斜杠后的内容)
2019/09/03 Javascript
python列表去重的二种方法
2014/02/14 Python
在Django中编写模版节点及注册标签的方法
2015/07/20 Python
python中子类继承父类的__init__方法实例
2016/12/15 Python
开源Web应用框架Django图文教程
2017/03/09 Python
Python实现图片尺寸缩放脚本
2018/03/10 Python
Python实现的序列化和反序列化二叉树算法示例
2019/03/02 Python
在tensorflow中设置保存checkpoint的最大数量实例
2020/01/21 Python
在jupyter notebook中调用.ipynb文件方式
2020/04/14 Python
解决python cv2.imread 读取中文路径的图片返回为None的问题
2020/06/02 Python
详解scrapy内置中间件的顺序
2020/09/28 Python
基于Python爬取素材网站音频文件
2020/10/21 Python
高中地理教学反思
2014/01/29 职场文书
小学英语教师先进事迹
2014/05/28 职场文书
英语专业自荐书
2014/06/13 职场文书
4s店活动策划方案
2014/08/25 职场文书
私营公司诉讼代理委托书范本
2014/09/13 职场文书
离婚协议书怎么写的
2014/12/14 职场文书
公积金具结保证书
2015/05/11 职场文书
党课主持词大全
2015/06/30 职场文书