Angular2+:NgModel / NgControl 如何在内部处理从视图到模型的更新?
Angular2+: how does NgModel / NgControl internally handle updates from view to model?
我正在深入研究双向数据绑定的工作原理。我目前对来自视图(例如 input
元素)的更新如何在内部传播到 NgControl
感到困惑。
在 ControlValueAccessor
的定义中提到 registerOnChange
负责视图 -> 模型更新 (docs where they say it, and 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
}
Uncommenting/commenting 指示的行允许我们 allow/block 从输入元素到模型的更新。但我对此感到困惑,因为在本示例中使用的 DefaultValueAccessor 的源代码中,onChange
并没有真正做任何事情:(_:any) => {}
.
所以,我希望在引擎盖下,例如在 ng_model.ts 或相关 类 之一中,如 NgControl
或 FormControl
,ValueAccessor 的 onChange
函数发生了一些事情;设置它或将其包装在另一个函数中,可能是代理或其他任何东西。我没有找到任何东西。然后我继续寻找一些代码,其中侦听器(对于 input
事件,更明确地说)明确绑定到输入元素,但也没有运气。
我注意到 OnChanges
function calls _setValue
,但我不确定在深入研究变化检测的内部时我是否朝着正确的方向前进,因为我希望聆听 DOM 与 ControlValueAccessors
and/or FormControl/AbstractControl
有关
有人想详细说明它是如何工作的吗? :-)
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);
});
}
我正在深入研究双向数据绑定的工作原理。我目前对来自视图(例如 input
元素)的更新如何在内部传播到 NgControl
感到困惑。
在 ControlValueAccessor
的定义中提到 registerOnChange
负责视图 -> 模型更新 (docs where they say it, and 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
}
Uncommenting/commenting 指示的行允许我们 allow/block 从输入元素到模型的更新。但我对此感到困惑,因为在本示例中使用的 DefaultValueAccessor 的源代码中,onChange
并没有真正做任何事情:(_:any) => {}
.
所以,我希望在引擎盖下,例如在 ng_model.ts 或相关 类 之一中,如 NgControl
或 FormControl
,ValueAccessor 的 onChange
函数发生了一些事情;设置它或将其包装在另一个函数中,可能是代理或其他任何东西。我没有找到任何东西。然后我继续寻找一些代码,其中侦听器(对于 input
事件,更明确地说)明确绑定到输入元素,但也没有运气。
我注意到 OnChanges
function calls _setValue
,但我不确定在深入研究变化检测的内部时我是否朝着正确的方向前进,因为我希望聆听 DOM 与 ControlValueAccessors
and/or FormControl/AbstractControl
有人想详细说明它是如何工作的吗? :-)
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);
});
}