我正在深入研究双向数据绑定的工作方式。目前,我对视图的更新(例如,input
元素)如何在内部传播到NgControl
感到困惑。
在ControlValueAccessor
的定义中,它提到registerOnChange
负责视图->模型更新(docs where they say it和src)。通过一个简单的指令,我们可以将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或相关类之一(例如NgControl
或FormControl
中)中,ValueAccessor的onChange
函数发生了某些情况;设置它或将其包装在另一个函数(例如代理或其他函数)中。我什么都没找到。然后,我继续寻找一些将侦听器(更明确地说是input
事件的侦听器)绑定到输入元素的代码,但也没有运气。
我注意到了OnChanges
function calls _setValue
,但是在深入了解变化检测的内部时,我不确定是否朝着正确的方向前进,因为我希望侦听DOM中的变化会与ControlValueAccessors
和/或FormControl/AbstractControl
任何人都想详细说明它是如何工作的? :-)
答案 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);
});
}