Going back from two-way binding to one-way
The template form of two-way binding is really a one-shot piece of syntax sugar in Angular. At bottom it packages binding the data once and having a change in the data fire an event callback and update, all into one thing, which is the default banana-in-a-box form.
And of course you can take control of this yourself. Which is to say, when I need to, I can go back by hand to that “tedious” one-way data flow mechanism and point the event callback at my own method, so the whole process runs at a granularity I control.
The default form has a very clear precondition, which is that both sides are objects you can modify directly, otherwise updating straight back the other way errors out. Or say what I want is to do some custom preprocessing on the data coming back, and in that case I have to take control myself.
<input
type="text"
[ngModel]="promoCode"
(ngModelChange)="onPromoCodeChange($event)"
[ngModelOptions]="{ standalone: true }"
placeholder="Type any letter"
>
\[ngModel] appearing on its own here means binding, or the way I personally read it, subscribing.
(ngModelChange) when the bound object changes, this callback fires, and its $event hands back the changed value, whose type is the same as the type given at binding time.
\[ngModelOptions]="{ standalone: true }" this is the key to template syntax and reactive forms still working when they’re mixed. Normally any child node of a reactive form has to name its own formControlName, and it errors outright if there isn’t one. Under the current template form there’s no way to hang a legal reactive control on it, so an extra declaration is naturally needed, which makes this one necessary too.
Translation note. I wrote this in Chinese. This English version is an LLM translation, so the wording is not mine even though the thinking is. Original: 雙向綁定回歸單向.