I am writing an angular 2 application where I try to use ChangeDetectionStrategy.OnPush everywhere, for performance reasons. I have a complex component that needs OnPush in order to work smoothly, which contains another component that is displaying a form (created with FormBuilder). I now noticed that when I click on a slider, the internal value of it is updated (i.e. form.value), but the slider component does not visualize this new value, i.e. it is stuck at the old position.
My first idea to fix this, was to set the leaf component's change detection strategy to DEFAULT, but this had no effect as apparently this requires changing the change detection strategy of its parent components too (which is not possible in my application).
Then I came up with this idea:
@Component({
...
})
class MyComponent implements OnInit {
constructor(private zone: NgZone) {}
ngOnInit() {
INIT_FORM();
this.form.valueChanges
.subscribe(() => {
this.zone.run(() => {});
});
}
}
but it has no effect.
Is there any possibility to make angular 2 forms work inside a component that uses OnPush?
The OnPush strategy changes Angular's change detection behavior in a similar way as detaching a component does. The change detection doesn't run automatically for every component anymore. Angular instead listens for specific changes and only runs the change detection on a subtree for that component.
Input Reference But with OnPush strategy, the change detector is only triggered if the data passed on @Input() has a new reference. This is why using immutable objects is preferred, because immutable objects can be modified only by creating a new object reference.
What is Change Detection Strategy in Angular ? Angular Change Detection Strategy are the methods by which the updates to the component is tracked and component is triggered to Re-render.
Select the devices in which you want to enable/disable change detection. Click on the 3 horizontal dots at the top right corner to get device option list. Click on "Enable Change Detection" from the given list. Select "Enable" or "Disable" operation based on your requirement.
Not tested myself but invoking change detection manually might do what you want:
@Component({
...
})
class MyComponent implements OnInit {
constructor(private cdRef: ChangeDetectorRef) {}
ngOnInit() {
INIT_FORM();
this.form.valueChanges
.subscribe(() => {
this.cdRef.detectChanges();
});
}
}
Let me respond with something that i have been answering on another posts, you could do something better !, let me know if this works :
when you use reactive forms you can use a really cool method called updateValueAndValidity(); that triggers a change detection.
private changeControlValue(control, value: number) {
control.setValue(value);
control.updateValueAndValidity();
}
You can also use this method when updating the validators added to a form, example:
this.control.setValidators([Validators.required, Validators.minLength(5)]);
control.updateValueAndValidity();
This should do the trick ! I think this is one of the best adventages of using reactive forms or form controls against ng-model.
I don't recommend to use valueChanges at your form as you are open to forget to de-subscribe and create a memory leak, even you remember it can be tedious to create this flow.
And remember, when using onPush change detection only three things are going to be detected as changes by Angular:
1- Inputs and Outputs. 2- Html events that the user can do, like (click). 3- Async events like subscriptions.
I hope i helped you !.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With