Angular2 +:NgModel / NgControl如何在内部处理从视图到模型的更新?

时间:2018-08-24 07:37:28

标签: javascript angular typescript angular2-directives angular2-ngmodel

我正在深入研究双向数据绑定的工作方式。目前,我对视图的更新(例如,input元素)如何在内部传播到NgControl感到困惑。

ControlValueAccessor的定义中,它提到registerOnChange负责视图->模型更新(docs where they say itsrc)。通过一个简单的指令,我们可以将input放在相同的[(NgModel)]元素上,例如<input [(NgModel)]=stuff myInspectorDirective>,我试着玩这个游戏。

constructor(private ngControl: NgControl) { }
ngOnInit(): void {
    // this.ngControl.valueAccessor['onChange'] = () => {}; 
    // uncommenting the above line prevents updates from view to model 
}

取消注释/注释所指示的行允许我们允许/阻止从输入元素到模型的更新。但是我对此感到困惑,因为在DefaultValueAccessor的源代码中,本示例中使用的源代码onChange实际上并没有做任何事情:(_:any) => {}

所以,我希望在幕后,例如在ng_model.ts或相关类之一(例如NgControlFormControl中)中,ValueAccessor的onChange函数发生了某些情况;设置它或将其包装在另一个函数(例如代理或其他函数)中。我什么都没找到。然后,我继续寻找一些将侦听器(更明确地说是input事件的侦听器)绑定到输入元素的代码,但也没有运气。

我注意到了OnChanges function calls _setValue,但是在深入了解变化检测的内部时,我不确定是否朝着正确的方向前进,因为我希望侦听DOM中的变化会与ControlValueAccessors和/或FormControl/AbstractControl

有关

任何人都想详细说明它是如何工作的? :-)

1 个答案:

答案 0 :(得分:1)

ControlValueAccessor.registerOnChange由NgForm提供。

1)NgModel已在NgForm中注册(请参见https://github.com/angular/angular/blob/master/packages/forms/src/directives/ng_model.ts

in NgModel.ngOnChanges: this._setUpControl calls this.formDirective.addControl

2)NgForm调用共享的setUpControl函数(请参见https://github.com/angular/angular/blob/master/packages/forms/src/directives/ng_form.ts

import { setUpControl } from './shared';
NgForm.addControl calls setUpControl

3)setUpControl寄存器更改事件处理程序(请参见https://github.com/angular/angular/blob/master/packages/forms/src/directives/shared.ts

setUpControl calls setUpViewChangePipeline

function setUpViewChangePipeline(control: FormControl, dir: NgControl): void {
  dir.valueAccessor !.registerOnChange((newValue: any) => {
    control._pendingValue = newValue;
    control._pendingChange = true;
    control._pendingDirty = true;

    if (control.updateOn === 'change') updateControl(control, dir);
  });
}