-
Notifications
You must be signed in to change notification settings - Fork 24.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reactive Form change through ControlValueAccessor doesn't update view #13792
Comments
Can you recheck this on the latest version, all appears to be working fine for me |
The plunker is up to date (2.4.9) and still displays issue - are you saying you don't see issue in the plunker? |
@tiagoroldao what is meant to happen? I click the ngmodel button and the 2 inputs + 1 label update. |
@Toxicable summing it up:
Bottom (buggy) form using
|
Sorry, ignore the above. I reread your issue see whats going on here, I don't know the inner workings overly well but it looks to me like a limitation of Reactive Forms currently not necessarily a bug. Maybe opening a Feature request for this after checking if there isn't one already |
I do see it as a bug - when updating the reactive formControl through the directive, it specifically updates it without updating views (I'm thinking it assumes it isn't needed as it came from the view, but it doesn't account for multiple uses of the same formControl) The culprit is here:
Although I don't know the full performance implications of removing |
By the way, the problem is fixed by removing the assumption that the views do not need to be updated when a change comes from view to model. Fixed here: Still I can't presume to know the implications of this. @DzmitryShylovich who could verify this? |
For those who came from google with this issue like me, there's a workaround that saved me: control.valueChanges.subscribe(e => {
control.setValue(e, {emitEvent: false});
}); |
Facing the same issue. Thank you @Ledzz for the workaround. |
@Ledzz solution works, but be aware of the jumping cursor in IE11: I need a input field and a select to work on the same control. Following workaround worked for me: <form [formGroup]="form">
<input type="text" formControlName="bewarage">
<select formControlName="bewarage" #s
[value]="form.get('bewarage').value"
(change)="form.get('bewarage').setValue(s.value, {emitEvent: false})">
<option *ngFor="let b of bewarages" value="{{b}}">{{b}}</option>
</select>
</form> try it: https://plnkr.co/edit/WaLHOlcNAVbSAH8m0a7o?p=preview On topic: In my opinion this is an unexpected behaviour, so I see it as a bug not a missing feature. |
No news in this one? I've the same issue with ng4 and ng5 as well. |
Thanks for the solution. But i hope this bug fixed soon. |
I'm having the same problem. The workaround from @Ledzz does not work for me. I also tried calling ChangeDetectorRef.detectChanges() in my controller, but that doesn't help either. |
I'm having the same problem. When I do this from my controller:
With this template:
My custom component that implements ControlValueAccessor, never gets the new value passed to it's writeValue method. There appear to be no workarounds. |
If you only have a subset of form fields you know to be 'duplicated' you're slightly better off using
This will probably mitigate issues with browser controls quirks such as the above mentioned IE11 issue. Still strikes me as bizarre this is the 'by design' behavior. I suppose it is a performance issue. Everything in angular magically binds - except for the simplest forms :-/ |
I have the same problem as well. Both setValue doesn't cause a change nor is valueChanges firing when values are set. |
... the problem is still valid for Angular 5.2.4 https://stackblitz.com/edit/mlc-two-inputs-same-formcontrol?file=app%2Fapp.component.html |
There are two points to note about the following code: http://plnkr.co/edit/LXyo6uHdbEpP3feudYoo?p=preview First, it's worth to say that in this example: there is a subtle difference between the template driven and reactive versions:
We can avoid this difference by wrapping the inputs in a form. Second, the two versions (template driven and reactive) are not really equivalent. And the problem (if it's really a problem), exists also in the template driven forms as in the reactive ones. Here http://plnkr.co/edit/mPDLG7MZlp6KRvkYBN89?p=preview I give the equivalent reactive version of the template driven one and the template driven version equivalent to the reactive one. |
This problem still exist. No fix from angular yet. I am facing the same issue for custom radio button control using reactiveforms |
If you have any solution please share, i have the same issue with custom checkbox, currently using formcontrolname with input to update which is not the best practice |
I am doing this way to solve the issue. Its working
`<div class="d-inline-flex" (click)="toggle()">
`import { Component, OnInit, Input, forwardRef, Self, Optional } from '@angular/core'; @component({ @input() label = ''; public selected = false; constructor(public ngControl: NgControl) { private propagateChange = (_: any) => { }; public toggle(): void { private update(value: any): void { public writeValue(value: any): void { public registerOnChange(fn: any): void { public registerOnTouched(fn: any): void { public setDisabledState(isDisabled: boolean): void { public ngOnInit(): void { |
Well i have a working solution but it requires some input directives, however i wanna do it without the help of inputs only using formcontrolname, its kinda essential in my projects |
This worked for me for both a reactive form and a non-reactive one:
The template looks like this:
|
@chrisv2 Have you tried setting it this way?
|
Only this solution works for me, simple and straightforward. |
Another solution that worked for me, using timeout, bit hacky but does a job, just wrap the patchValue or setValue with timeout
|
Got stuck with this issue in a scenario pretty close to the @maxime1992 colorpicker. Very disappointed when I saw this issue open for years... If not recognised as an issue it would be nice to hear the reasons from someone in angular core team. in our cases, only solution was to trigger a |
While this works definitely, it's not optimal as Angular needs another ChangeDetection cycle to pick up your changes. Did you try to call |
I did try the change detection, but did nothing. What I finally did, I removed the [ngModel], and only used the reactive approach. In case you have [ngModel] and reactive form together, another solution to update the view via setting the models with values, like this.filterTags = someValue. after the patching, in this case it updates the view |
Almost 4 years for this bug.. 👎 I have a stepper in my app and last step is a summary of previous forms. Well I have to use same form groups at the last step, but as it is formcontrols duplication summary is not updated anytime |
I'm not sure if this is a bug actually. The point of the ControlValueAccessor is to act as a bridge between the control and the native element, as stated in the docs again. If you override the default provider, you need your own implementantion, includeing the native element update. I have a currency control, where I want to keep the input display value masked, but record it as a numeric value in my formControl, so I can submit it straight away. If the Control Value Accessor keeps syncing the formControl to the native element, this will turn impossible. It seems reasonable for me that we should use renderer to set the native element input. I think the confusion is due to the fact that this seems not to be needed in the template form, because the model is updated with the simple property change, but only because that's how ngModel behaves. The flow behind the reactive forms is different. That being said, it only seems reasonable after a very long time that I spent not being able to understand what was happenning. I think the docs could get some attention not only for this issue, but for the ControlValueAccessor in general. I found really hard to understand the correct implementation of it at first, specially for simple cases, because most articles I found online were either template forms and the simple property update would be enough to update the view, or form groups with child controls, which, in the end, delegated the view update to the child controls. A simple mask input example would be better to understand the purpose and how the ControlValueAccessor works. Again, for the forms docs, I found the (very cool) data flow diagrams a bit misleading, because they lead you to think that the view to model and vice-versa flow is done through the FormControlDirective, when in fact it seems to be trough the ControlValueAccessor. |
I am also facing this issue. |
I guess triggering change detection could help in case of writing value from outside |
Same as @guilhermetod, I'm not sure every usecase given here is a bug. I took the stackblitz example given earlier and fixed it: https://stackblitz.com/edit/angular-urxsu8?file=src%2Fmain.ts In that particuliar case, the inner model was not updated meaning the on the subsequent I'll close this for now. If someone can provide a stackblitz repro of this issue after taking my remarks into account, I'll reopen. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
I'm submitting a ... (check one with "x")
Current behavior
When updating a value through a form field that uses the formControl directive, the view isn't updated. When, say, two fields hold the same form control, changing one does NOT change the other.
This does happen when using NgModel, and does happen when calling
formControl.setValue(newVal)
Expected behavior
Behaviour is expected to be the same in NgModel as when using Reactive FormControls
Minimal reproduction of the problem with instructions
http://plnkr.co/edit/LXyo6uHdbEpP3feudYoo?p=preview
What is the motivation / use case for changing the behavior?
The contract custom form fields have when using the
ControlValueAccessor
interface is broken. A good example is http://valor-software.com/ng2-bootstrap/#/buttons#radio - which works currently only with NgModel, as it requires updating the view on all relevant buttons on value change.When using a set of buttons with reactive forms, currently, a
(click)
based hack needs to be put in place:Please tell us about your environment:
OS Not relevant
Angular version: 2.4.1
Browser: Chrome 55
Language: TypeScript 2
The text was updated successfully, but these errors were encountered: