Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngIf not detecting var change

I am using the greensock animation library to animate some components (as you would expect). I am experiencing an issue when I am updating a variable in the onComplete function which is bound to a *ngIf. For some reason, angular is not detecting the update to the variable in the callback.


Intended functionality:
1. click grey image.
2. pink image fades out
3. one of the grey images dissapears.

Current functionality:

1. click grey image.
2. pink image fades out
3. (nothing happens)
4. click grey image - again.
5. one of the grey images dissapears.

I have a plunkr for the following...

declare var TweenMax; // defined in index.html
@Component({
  selector: 'my-app',
  template: `
    <img *ngIf="leftVisible" src="http://placehold.it/350x150" (click)="animate(-1)"/>
    <img *ngIf="rightVisible" src="http://placehold.it/350x150" (click)="animate(1)"/>
    <img #otherImage src="http://placehold.it/350x150/ff00ff/000000"/>
  `,
})
export class App {
  @ViewChild('otherImage') otherImageElement;

  private leftVisible: boolean;
  private rightVisible: boolean;

  constructor() {
    this.leftVisible = this.rightVisible = true;
  }

  private animate(_direction: number){
    var tween = TweenMax.to(this.otherImageElement.nativeElement, 1, {
      opacity: 0,
      onComplete: () => {
        console.log("anim complete");
        this.rightVisible = false;
      }
    }
  };
}

You can see in the console that the callback fires successfully and updates the variable, however the element which is bound to the *ngIf does not change until you click one of the grey images a second time.

How do I get this to update as intended in the onComplete callback?

like image 793
Zze Avatar asked Mar 13 '17 01:03

Zze


1 Answers

please refer to this Angular 2 documentation: Lifecycle Hooks

According to the documentation,

Angular's unidirectional data flow rule forbids updates to the view after it has been composed. Both of these hooks fire after the component's view has been composed.

Option1: use ngZone.run to notify angular to render the view again.

// import ngZone from @angular/core first.
this.ngZone.run(() => {
  console.log("anim complete");
  this.rightVisible = false;
});

Option2: use ChangeDetector to let angular to render the view again.

import {ChangeDetector} from '@angular/core';

this.rightVisible = false;
this.cd.detectChanges();

Refer this plunker that contains the upper code block.

like image 94
Pengyy Avatar answered Oct 12 '22 11:10

Pengyy