Angular 5 指令中的实时变化检测

Angular 5 realtime Change Detection in Directive

我非常了解 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 type="number" myNumber [(ngModel)]="number1" />
<input type="number" myNumber [(ngModel)]="number2" />
<input type="number" myNumber [(ngModel)]="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');
}

#问题:

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'

#我想简化的解决方案:

在组件中,我们可以在 calculate() 方法中的每个模型更改后调用 changeDetection()。这将自动触发指令的更改检测挂钩。

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
}

#问题:

如何在每次模型更改后无需手动编写 ref.detectChanges() 立即实现这一点并更改检测?

希望这个例子对遇到同样问题的各位有用

更新:

我第一个 post 中的上述示例实际上有效:) 这是我的错误,我会详细解释它。

在我的实际实现中,我将数字指令应用于所有数字输入字段。 指令正在侦听模糊模型更改并应用一些数字舍入。

一切正常 -> 我们插入一个数字,onBlur 数字将被舍入、应用管道等。

问题是当我有额外的计算方法来重新计算另一个字段时:

例如:

calculate() {
  this.number1 = 10; // changing ngModel of number1
  // after model change number1 will be rounded (handled) in a directive
  const number2 = 20; // this is not a model so it's not handled by directive
  // I used non-model variable in my calculation that is not handled by directive
  this.number3 = this.number1 * number2; // changing ngModel of number3
}

通过在计算中使用非模型变量 - 该值未四舍五入,因此我的方法与指令计算四舍五入不匹配,导致数字略有不同。

这就是为什么我认为 Angular(指令)没有在正确的时刻检测到变化。

抱歉,伙计们,但我希望这个订阅检测变化的例子能对别人有所帮助!!

:: 欢呼::

约瑟普