我非常了解 Angular 的更改检测是如何工作的,以及我们如何使用 OnChanges 挂钩来检测@Input
属性更改,以及订阅 ngModel valueChanges 例如指令或组件等。
谁能解释这里发生了什么:
# 自定义指令:
假设我们有一个自定义指令 myNumber,它有一个 @Input() 属性 ngModel:
@Directive({
selector: "[myNumber]"
})
class MyNumberDirective implements OnChanges {
@Input() ngModel: any;
constructor(private model: NgModel) {
this.model.control.valueChanges.subscribe(data => {
console.log('directive model changes detected by model control value change subscription');
});
}
ngOnChanges(changes: SimpleChanges){
if(changes.ngModel){
console.log('directive input ngModel changes detected by OnChanges hook');
}
}
}
- 在上面的示例中,我将订阅设置为
@Input
属性 ngModel 和指令的模型对象更改。模型值更改时,应将更改记录在控制台中。
# 组件的模板:
<input type="number" myNumber [(ngModel)]="number1" />
<input type="number" myNumber [(ngModel)]="number2" />
<input type="number" myNumber [(ngModel)]="number3" (blur)="calculate()" />
我们在三个输入元素上应用了 myNumber 指令,每个输入元素都有 ngModel:number1、number2、number3。
最后一个输入在 blur 事件上调用 calculate() 方法。
# 组件的打字稿:
calculate() {
this.number1 = 10; // changing ngModel of first input
console.log('number1 changed in a calculate method');
this.number2 = 20; // changing ngModel of second input
console.log('number2 changed in a calculate method');
this.number3 = 30; // changing ngModel of third input
console.log('number3 changed in a calculate method');
}
- 每次模型更改后,我都会在 calculate() 方法中记录一条消息。
- 指令正在侦听 ngModel 更改,它还将为每个模型值更改记录两条消息。
# 问题:
Angular 将执行calculate()
方法,更改所有三个模型,然后检测更改并在指令中触发 cd 钩子:
// calculate() log messages first:
'number1 changed in a calculate method'
'number2 changed in a calculate method'
'number3 changed in a calculate method'
// then number1 model change messages in a directive:
'directive model changes detected by model control value change subscription'
'directive input ngModel changes detected by OnChanges hook'
// then number2 model change messages in a directive:
'directive model changes detected by model control value change subscription'
'directive input ngModel changes detected by OnChanges hook'
// then number3 model change messages in a directive:
'directive model changes detected by model control value change subscription'
'directive input ngModel changes detected by OnChanges hook'
# 解决方案我想简化:
在组件中,我们可以changeDetection()
在每次模型更改后调用该calculate()
方法。这将自动触发指令的变更检测钩子。
constructor(private ref: ChangeDetectorRef) {}
calculate() {
this.number1 = 10; // changing ngModel of first input
console.log('number1 changed in a calculate method');
this.ref.detectChanges(); // triggering detect changes manually
this.number2 = 20; // changing ngModel of second input
console.log('number2 changed in a calculate method');
this.ref.detectChanges(); // triggering detect changes manually
this.number3 = 30; // changing ngModel of third input
console.log('number3 changed in a calculate method');
this.ref.detectChanges(); // triggering detect changes manually
}
- 这样 Angular 将立即更改模型并在指令内调用更改检测钩子。
# 问题:
ref.detectChanges()
如何在每次模型更改后立即实现并更改检测而无需手动编写?
我希望这个例子对所有遇到同样问题的人有用