目录
angular变化检测的概述
什么是angular变化检测
触发事件改变的情况
angular 获取变化通知
变化检测策略
Default:
Onpush:
需要用到OnPush策略的情况
例子
参考
Angular提供了数据绑定的功能。所谓的数据绑定,就是把组件类中的数据与页面的DOM元素关联起来,当数据发生变化时,Angular能够监测到这些变化,并对其绑定的DOM元素进行相应的更新;反之,当检测到视图上绑定的值发生改变时,则回调对应的绑定函数。【检测视图与模型之间绑定的值是否发生了改变。】
上述三种情况都有一个共同点,即这些导致绑定值发生改变的事件都是异步发生的。如果这些异步的事件在发生时能够通知到Angular框架,那么Angular框架就能及时的检测到变化。
通常,异步事件的发生会导致组件中的数据发生变化,但Angular并不是去捕获对象的变动,而是在适当的时机去检测对象的值是否被改变。这个时机是由NgZone这个服务去掌控的,它会获取整个应用的执行上下文,能够对相关的异步事件的发生、完成、异常等进行捕获,然后驱动Angular的变化检测机制去执行。
Angular接入了ZoneJS,由它监听了Angular所有的异步事件。Zone有一个叫猴子补丁的东西。在Zone.js运行时,就会为这些异步事件做一层代理包裹,也就是说Zone.js运行后,调用setTimeout、addEventListener等浏览器异步事件时,不再是调用原生的方法,而是被猴子补丁包装过后的代理方法。代理里setup了钩子函数, 通过这些钩子函数, 可以方便的进入异步任务执行的上下文。
Angular为每一个组件都创建了一个变化监测类的实例,该实例提供了一些方法可以手动管理变化监测。当发生变化时,Angular会从根组件到子组件来监测每个组件是否发生了变化。Angular本身并不知道是哪个组件发生了变化,所以才遍历所有组件进行监测。
但是开发者是知道哪个组件发生了变化,所以可以通过变化监测类的实例提供的方法给这个组件做标记,来通知Angular仅仅监测这个组件所在的路径上的组件就可以了。
NgZone通知框架在异步操作发生时执行变更检测,因此当mousemove事件触发时它也会触发变更检测。我们可能不希望每次触发mousemove时都执行更改检测,因为它会降低我们的应用程序速度并导致非常糟糕的用户体验。
父组件:
{{ star | json }} <button type="button" (click)="changeStar()">改变明星属性</button> <button type="button" (click)="changeStarObject()">改变明星对象</button> <app-child [star]="star" ></app-child> star: Star = new Star('周', '杰伦'); changeStar() { this.star.firstName = '吴'; this.star.lastName = '彦祖'; console.log('更改属性'); } changeStarObject() { this.star = new Star('刘', '德华'); console.log('更改对象'); }子组件:
<span>{{star.firstName}} {{star.lastName}}</span> changeDetection: ChangeDetectionStrategy.OnPush // 使用Onpush策略就加这句话,使用default就不加这句话 ,在@Component({})里添加 @Input() star: any;截图如下:
default策略的情况:第一次渲染
点击第一个更改属性按钮
点击第二个更改对象按钮
default策略的情况下,父组件,子组件页面都正常地更新了。
OnPush策略的情况:其它都相同,不同的地方在于点击第一个更改属性按钮后:父组件更新了,子组件并未更新。
我们明确地告诉Angular我们的组件只依赖于它的输入,并且它们都是不可变的。然后,Angular假定子组件没有更改,并将跳过对该组件的检查。因为我们没有强制Star对象是不可变的,所以最终我们的模型与视图不同步.
点击第二个更改对象按钮,子组件视图更改的原因:创建了新实例,更改检测知道Star对象已更改,会继续进行全局的检查。
https://www.cnblogs.com/hanshuai/p/9362660.html (是一个系列,有3篇)
映射类型(keyof, Pick<T, K>)
svg 可自适应 描边 圆锥渐变
