angular
angular copied to clipboard
There is a problem in updating NgControl when using OnPush strategy
I have a edit form component with onPush strategy.
In template there is input field:
<input type="text" class="form-control" id="receiveCode" required [maxlength]="25" [(ngModel)]="receiveCode" [ngClass]="setCssValidityClass(receiveCodeCtrl)" #receiveCodeCtrl="ngForm">
By default receiveCode is empty. I update receiveCode in OnActivate method by calling api.
@override
Future<void> onActivate(RouterState previous, RouterState current) async {
receiveCode = await _receiveAPIService.createNewReceiveCode();
cdr.markForCheck();
}
I added some debug code to method setCssValidityClass:
Map<String, bool> setCssValidityClass(NgControl control) {
print('validate: $receiveCode valid is ${control.valid} value = ${control.value}');
if (control.control != null) {
print(control.validator(control.control));
}
final validityClass = control.valid == true ? 'is-valid' : 'is-invalid';
return {validityClass: true};
}
After page loaded in console:
receiveCode = ; valid is true; value = null {required: true} receiveCode = 091.05.2019; valid is false; value = {required: true}
On page I see 091.05.2019
in input field and it has is-invalid
css class.
I think markForCheck should update value in NgControl.
- Dart VM version: 2.3.1 (Tue May 21 19:28:38 2019 +0200) on "windows_x64"
- angular: 5.3.0
- angular_forms: 2.1.2
- Chrome
To be clear, is the control supposed to be valid at this point, but it's not?
I wonder if setCssValidityClass(receiveCodeCtrl)
is simply being checked before the control, so it hasn't updated yet. @Cododoc Can you double check if this is the case? Try setting breakpoints in the control and your method to see if they're both updating, just in the wrong order?
@alorenzen @TedSander Any ideas?
@leonsenft , I create example project to show a problem: https://github.com/Cododoc/onpush_example
Yes. Controller has wrong state, when user can see data in input field.
Can you confirm if this is still an issue in 6.0.0-alpha?
We did change NgModel
from ComponentState
back to a normal directive in that release (it was the only ComponentState
directive...), so maybe that changed things here.
That said, NgModel
updates it's underlying Control
value in ngAfterChanges()
, so I would expect that setCssValidityClass()
could be called before Control.updateValue()
.
@alorenzen , there is same behavior on angular 6.0.0-alpha.
Is there any progress?