Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular2 form + async validation + ChangeDetectionStrategy.OnPush = no view refresh?

[angular2 RC4 + @angular/forms module]

I have a component using OnPush change detection containing a FormGroup. This form contains a FormControl with an async validator.

When the validation is complete (no more pending), the view is not refresh. Only the input blur event makes view refresh..

If I remove the OnPush change detection, it works properly.

This plunker demonstrates it.

Is it an angular bug or I'm doing something wrong?

like image 370
bertrandg Avatar asked Jul 20 '16 15:07

bertrandg


People also ask

What triggers OnPush change detection?

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 the difference between OnPush and default change detection?

OnPush means that the change detector's mode will be set to CheckOnce during hydration. Default means that the change detector's mode will be set to CheckAlways during hydration.

What is Changedetectionstrategy OnPush in angular?

The main idea behind the OnPush strategy manifests from the realization that if we treat reference types as immutable objects, we can detect if a value has changed much faster. When a reference type is immutable, this means every time it is updated, the reference on the stack memory will have to change.

In which situations will angular check for changes in a component using the OnPush change detection strategy?

An OnPush change detector gets triggered in a couple of other situations other than changes in component Input() references, it also gets triggered for example: if a component event handler gets triggered. if an observable linked to the template via the async pipe emits a new value.


1 Answers

Looks like you are missing the goal of using ChangeDetectionStrategy.OnPush.

You don't have any @Input property or | async pipe on your component, but it is only point of updating the view state with this strategy - when Input property updated (in ideal with a new object). So just get rid of it for current case

UPDATE

if you still insist on using OnPush in this case, for expected behavior you should trigger change detection manually.

Add import {..., ChangeDetectorRef} from '@angular/core'; and inject instance of it in constructor.

In your method you have to add this:

 uniqueNameAsync(control: FormControl): Promise<{[key: string]:any}>{
   return new Promise(resolve => {
       setTimeout(() =>{
            resolve(null);
            this.changeRef.markForCheck();
      }, 500);
   });
 }
like image 80
Oleg Barinov Avatar answered Nov 11 '22 11:11

Oleg Barinov