angular onpush模式下优先使用markForCheck手动标记为脏属性并调用检测更新
import { ChangeDetectorRef,Component ,Input,ChangeDetectionStrategy,SimpleChanges} from '@angular/core';
@Component({
selector: 'app-change-grandson',
templateUrl: './change-grandson.component.html',
styleUrls: ['./change-grandson.component.less'],
// changeDetection变化检测;Strategy 策略
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChangeGrandsonComponent {
@Input() position='下'
grandsoName = "河蟹"
constructor(private cdr: ChangeDetectorRef){}
ngOnChanges(changes: SimpleChanges): void {
//Called before any other lifecycle hook. Use it to inject dependencies, but avoid any serious work here.
//Add '${implements OnChanges}' to the class.
console.log(changes);
}
ngOnInit(): void {
//Called after the constructor, initializing input properties, and the first call to ngOnChanges.
//Add 'implements OnInit' to the class.
setTimeout(()=>{
this.grandsoName='大闸蟹'
// 用了onpush策略会触发检测更新,但是不一定检测这个组件,所以
// 需要手动标记为脏属性并调用检测更新
this.cdr.markForCheck()
//如果this.cdr.markForCheck()不起作用再试下面代码
// this.cdr.detectChanges()
},1500)
}
}
备注:如果通过服务修改组件的变量,他不属于下面场景的任何一个。所以触发下一辆变更检测没用。需要使用
this.cdr.detectChanges() 进行强行检测。
- 事件:页面 click、submit、mouse down……
- XHR:从后端服务器拿到数据
- Timers:setTimeout()、setInterval()
补充:
onPush策略下触发变更检测的时机
定时器已无法触发变更检测了
- 组件的@Input引用发生变化。
- 组件的 DOM 事件,包括它子组件的 DOM 事件,比如 click、submit、mouse down。
- Observable 订阅事件,同时设置 Async pipe。
- 手动使用ChangeDetectorRef.detectChanges()、ChangeDetectorRef.markForCheck()、ApplicationRef.tick()方法