angular 有关侦测组件变化的 ChangeDetectorRef 对象
我们知道,如果我们绑定了组件数据到视图,例如使用 <p>{{content}}</p>,如果我们在组件中改变了content的值,那么视图也会更新为对应的值。
angular 会在我们的组件发生变化的时候,对我们的组件执行变化检测,如果检测到我们的数据发生了变化,就会执行某些操作,如修改绑定数据的时候更新视图。
这样一来,当我们的组件数据比较多的时候,angular就会有很多操作在静悄悄地进行,一个规避这个问题的方法是,设置某个组件的变化检测策略为 'OnPush'。
使用 OnPush 会指引 angular 去检测那些引用发生变化的对象,而不是某个对象下的属性发生变化就执行变化检测的操作。
该方法有以下几个方法:
class ChangeDetectorRef {
markForCheck(): void
detach(): void
detectChanges(): void
checkNoChanges(): void
reattach(): void
}
detach 和 reattach
先来说 detach 和 reattach,顾名思义,顾名思义... 只可意会
detach 方法的用处是,告诉 angular,暂时不用管当前组件的变化了,也就是说,当我们在组件上调用 ChangeDetectorRef 的 detach 方法之后,angular 在该组件数据发生变化的时候,不再执行更新视图等操作。
相反的,reattach 就是让 angular 在组件数据发生变化的时候重新检测该组件的变化,在该组件数据变化的时候,执行如更新视图的操作。
import {ChangeDetectorRef, Component} from '@angular/core';
class DataProvider {
data = 1;
constructor() {
setInterval(() => {
this.data = this.data * 2;
}, 500);
}
}
@Component({
selector: 'live-data',
inputs: ['live'],
template: 'Data: {{dataProvider.data}}'
})
export class LiveData {
constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {}
set live(value) {
if (value) {
this.ref.reattach();
} else {
this.ref.detach();
}
}
}
@Component({
selector: 'app-root',
providers: [DataProvider],
template: `
Live Update: <input type="checkbox" [(ngModel)]="live">
<live-data [live]="live"></live-data>
`,
})
export class AppComponent {
live = true;
}

上面的例子中,当我们勾中 checkbox 的时候,会发现,右边的数字一直在更新,而当我们取消勾选的时候,数字停止了更新。
也就是说,当我们 detach 的时候,angular 从变化检测树上移除了该组件,reattach 的时候,angular 把该组件重新加到了变化检测树上。
markForCheck
说到这个就不得不说一说 angular 的 ChangeDetectionStrategy 了,参见另外一篇文章:todo
当我们调用 ChangeDetectorRef 的 markForCheck 方法之后,angular 会在变化检测周期中检测该组件,
如果我们设置了组件的 changeDetection 为 OnPush 的时候,不使用 markForCheck 方法我们更新数据视图是不会更新的。
@Component({
selector: 'cmp',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `Number of ticks: {{numberOfTicks}}`
})
export class Cmp {
numberOfTicks = 0;
constructor(private ref: ChangeDetectorRef) {
setInterval(() => {
this.numberOfTicks++;
// 如果我们不调用下面这一句,视图将不会更新
this.ref.markForCheck();
}, 1000);
}
}
@Component({
selector: 'app-root',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<cmp></cmp>`
})
export class App {}
detectChanges
检查一遍 变化检测器 (change detector) 和它的子检测器。
可以配合 ChangeDetectorRef 来实现局部变化检查。
有些時候,对于更新频繁数据量又很大的列表,我们不想 angular 在列表变化的时候马上更新视图,我们可以手动去调用 detectChanges 方法,去强制 angular 检查 组件数据的变化。
这样一来,就可以实现自主控制视图更新频率,而不用担心有太大的性能问题了。
checkNoChanges
检测该组件及其子组件,如果有变化存在则报错,用于开发阶段二次验证变化已经完成。
angular 有关侦测组件变化的 ChangeDetectorRef 对象的更多相关文章
- [从 0 开始的 Angular 生活]No.38 实现一个 Angular Router 切换组件页面(一)
前言 今天是进入公司的第三天,为了能尽快投入项目与成为团队可用的战力,我正在努力啃官方文档学习 Angular 的知识,所以这一篇文章主要是记录我如何阅读官方文档后,实现这个非常基本的.带导航的网页应 ...
- Angular动态创建组件之Portals
这篇文章主要介绍使用Angular api 和 CDK Portals两种方式实现动态创建组件,另外还会讲一些跟它相关的知识点,如:Angular多级依赖注入.ViewContainerRef,Por ...
- Unity3d修炼之路:载入一个预制体,然后为该对象加入组件,然后查找对象,得到组件。
#pragma strict function Awake(){ //载入一个预制体 资源必须在 Resources目录下 Resources.LoadLoad(); //载入后 必须演示样例化 Ga ...
- Bootstrap入门(十四)组件8:媒体对象
Bootstrap入门(十四)组件8:媒体对象 这是一个抽象的样式,用以构建不同类型的组件,这些组件都具有在文本内容的左或右侧对齐的图片(就像博客评论或 Twitter 消息等). 1.基本样式 2. ...
- Angular 监听路由变化
var app = angular.module('Mywind',['ui.router']) //Angular 监听路由变化 function run($ionicPlatform, $loca ...
- 【Angular】关于angular引用第三方组件库无法改变其组件样式 :host ::ng-deep
[Angular]关于angular引用第三方组件库无法改变其组件样式 :host ::ng-deep css修改:无效 .ant-input-affix-wrapper .ant-input:not ...
- Angular第三方UI组件库------ionic
一.Angular UI组件库 ------------ionic 1. 官网:https://ionicframework.com 文档:https://ionicframework.com/d ...
- 前端使用mobx时,变量已经修改了,为什么组件还是没变化,map类型变量,对象类型变量的值获取问题(主要矛盾发生在组件使用时)
前天我在使用一个前端多选框组件时遇到了一个问题,明明对象内的值已经修改了,但是组件显示的还是没有效果改变,以下是当时打出的log,我打印了这个对象的信息 对象内的值已经修改了但是组件还是不能及时更改, ...
- vue 监听父子组件传参,对象数据变化
watch:{ 组件传参的字段 :{ handler (newV, oldV){ 这里打印 newV, oldV 就可以看到数据变化了 } , immediate: true, // 重点 deep: ...
随机推荐
- python-创建进程的三种方式
目录 1,os.fork() 方法 2,Process方法 3,Pool方法 1,os.fork() 方法 import os ret = os.fork() if ret == 0: #子进程 pr ...
- angularjs工作原理解析
个人觉得,要很好的理解AngularJS的运行机制,才能尽可能避免掉到坑里面去.在这篇文章中,我将根据网上的资料和自己的理解对AngularJS的在启动后,每一步都做了些什么,做一个比较清楚详细的解析 ...
- underscore.js源码解析(五)—— 完结篇
最近公司各种上线,所以回家略感疲惫就懒得写了,这次我准备把剩下的所有方法全部分析完,可能篇幅过长...那么废话不多说让我们进入正题. 没看过前几篇的可以猛戳这里: underscore.js源码解析( ...
- 按照Right-BICEP要求设计四则运算3程序的单元测试用例
按照Right-BICEP要求: Right——结果是否正确? B——是否所有的边界条件都是正确的? I——能查一下反响关联吗? C——能用其它手段交叉检查一下吗? E——你是否可以强制错误条件发生? ...
- Controller与Switch建立连接
连接建立 控制器和交换机认识的过程. 用于交互Openflow版本,如果不同则没有后续. 同1. 特征请求,控制器询问交换机的特征信息. 交换机回复控制器,相当于把整个交换机的所有配置都告诉控制器了. ...
- hdu1242 Rescue DFS(路径探索题)
这里我定义的路径探索题指 找某路能够到达目的地,每次走都有方向,由于是探索性的走 之后要后退 那些走过的状态都还原掉 地址:http://acm.hdu.edu.cn/showproblem.php? ...
- lintcode-107-单词切分
107-单词切分 给出一个字符串s和一个词典,判断字符串s是否可以被空格切分成一个或多个出现在字典中的单词. 样例 给出 s = "lintcode" dict = [" ...
- 七周七语言之用ruby做点什么
如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/05/25/sevenlang-ruby/. 每学一 ...
- 软工网络15团队作业4——Alpha阶段敏捷冲刺-6
一.当天站立式会议照片: 二.项目进展 昨天已完成的工作: 完成对账单的编辑,删除等操作,以及开始服务器的编写工作 明天计划完成的工作: 记账功能基本完成,进一步优化功能与完善服务器 工作中遇到的困难 ...
- python/django将mysql查询结果转换为字典组
使用python查询mysql数据库的时候,默认查询结果没有返回表字段名称,不方便使用.为了方便使用一般会选择将查询结果加上字段名称以字典组的方式返回查询结果. 实现如下: def dict_fetc ...