Monday, 12 November 2018

Angular2+: how does NgModel / NgControl internally handle updates from view to model?

I am doing a deep dive into how two-way databinding works. I am currently puzzled by how updates from the view (say, an input element) propagate to NgControl internally.

In the definition of ControlValueAccessor it mentions that registerOnChange is responsible for view -> model updates (docs where they say it, and src). With a simple directive that we may put on the same input element as [(NgModel)], e.g. <input [(NgModel)]=stuff myInspectorDirective>, I tried playing around with this.

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

Uncommenting/commenting the indicated line allows us to allow/block updates from the input element to the model. But I'm puzzled by this because in the source code of DefaultValueAccessor, the one used in this example, onChange is not really doing anything: (_:any) => {}.

So, I would expect that under the hood, e.g. in ng_model.ts or in one of the related classes, like NgControl or FormControl, something happens with the onChange function from the ValueAccessor; setting it or wrapping it in another function, maybe a proxy, or whatever. I did not find anything. Then I went on looking for some code where listeners (for the input event, more explicitly) are explicitly bound to the input element, but no luck either.

I noticed that the OnChanges function calls _setValue, but I'm not sure if I'm going in the right direction when diving into the internals of change detection, as I would expect the listening to changes in the DOM to be related to ControlValueAccessors and/or FormControl/AbstractControl

Anyone feels like elaborating on how this works? :-)



from Angular2+: how does NgModel / NgControl internally handle updates from view to model?

No comments:

Post a Comment