Closed todoroff closed 2 years ago
As surprising as it might be, the observed behaviour actually corresponds to how Angular (and many other frameworks using data-binding) was designed.
To understand what is going on here let's consider a simpler example from this stackblitz: https://stackblitz.com/edit/angular-ivy-eeedib
The key piece of code is [value]="state"
which results in the following generated code: i0.ɵɵproperty("value", ctx.state);
. The property instruction will do the following:
state
value to the one seen previously;The crux is in the "update the DOM if the previously stored value and the current value are different" part - in the example stackbitz the state
value never changes after the initial input! It is always equal to "'Never change'" and thus Angular never writes back to the DOM! This makes total sense as Angular is working hard in order to avoid unnecessary DOM manipulation.
What might be helpful here is a different mental model: instead of thinking of the model variable as "always being synchronized with the DOM" the actually implemented mental model is closer to "update DOM value when the variable value changes". This is how Angular was designed and this is the design that is followed by other frameworks, ex.: https://svelte.dev/repl/d0e99c1c845f4c9197429d2f679a52ca?version=3.44.2
It is kind of a corner and tricky use-case but the one that makes sense from the design point of view (even if it might be surprising to framework users).
In terms of work-arounds - doing changes manually in the DOM is the best I can think of right now.
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.
Which @angular/* package(s) are the source of the bug?
Don't known / other
Is this a regression?
No
Description
I've got the following component
TS:
HTML:
I would expect that once I start typing in any of the two input fields, their value will first turn into "Never change" and then stay that way as I keep typing. However, that only works properly the first time.
What happens is that the first time I type a character in one of the fields, the DOM value of both turns into "Never change". However, if I keep typing, the DOM value of the input I'm typing into, gets out of sync with the actual state variable.
I've also noticed that if in the onChange handler I set state to a random value, it works as expected. It's only a problem when I set it to the same value every time.
I've also tried using [value] and (input) instead of [ngModel] and (ngModelChange), but I'm getting the same issue.
The problem doesn't appear to be limited to just input fields either. I've tried on select elements where I want to run some validation in an onSelect handler and not update the DOM value with the selected option if the check fails.
If this is not a bug, is there a proper way to achieve this? I'd like the DOM value to be bound to the state value at all times, so I can be sure that what's in the DOM is a function of what's in state.
Please provide a link to a minimal reproduction of the bug
https://codesandbox.io/s/practical-shadow-ui72r?file=/src/app/app.component.ts
Please provide the exception or error you saw
No response
Please provide the environment you discovered this bug in (run
ng version
)No response
Anything else?
No response