Search code examples
javascriptangularng-class

angular 2.0 ngClass is not updated on timeout


I'm using Angular 2.0 beta 15.

Initially I was experiencing this problem while developing an app. Then I decided to try the simplest possible case to reproduce it. See the code below

//our root app component
import {Component} from 'angular2/core'

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
      <h2 [ngClass]="{'red-heading':isAlertOn, 'blue-heading':!isAlertOn}">Hello {{name}}</h2>
    </div>
  `,
  directives: []
})
export class App {
  isAlertOn:boolean;

  constructor() {
    this.name = 'Angular2';
    this.isAlertOn = false;
  }

  (function(){
    setTimeout(function(){
      console.log("in here");
      this.isAlertOn = true;
    },2000);
  })();
}

Plnkr

Since I'm using animations in my application I want to trigget class changing with a delay. In order to do that I'm using setTimeout.

I've read that in general all the changes are handled by NgZone manually (for some older alpha version I think). Right now those changes should be handled automatically. Either I'm missing something (still new in angular 2.0) or there might be a different approach.

Thank you in advance guys.


Solution

  • ---------------------------------------------New Updates 2016-04-26 15:28-------------------------------------------

    Ok I just figure out the way using CSS animation:

    in the css do this:

    @keyframes blueToRed{
      0% {color: blue}
      100% {color:red;}
    }
    
    .blue-to-red-heading {
      animation-name: blueToRed;
      animation-duration: 2s;
      /*animation-delay:2s; */ /*uncomment this for delays*/
      animation-fill-mode: forwards;
    }
    

    Then in app.ts

    //our root app component
    import {Component} from 'angular2/core'
    
    @Component({
      selector: 'my-app',
      providers: [],
      template: `
        <div>
          <h2 [ngClass]="{'blue-to-red-heading':isAlertOn}">Hello {{name}}</h2>
        </div>
      `,
      directives: []
    })
    export class App {
      isAlertOn:boolean;
    
      constructor() {
        this.name = 'Angular2';
        this.isAlertOn = true;
      }
    }
    

    --------------------------------------------------Original Answer------------------------------------------------------------- I think you got a great question.

    I cannot figure out why exactly, but the problem lies in the immediate function.

    Once you declare your function without running it immediately on the declaration. It works.

    And yes another thing: the setTimeout seems to mess up the "this"...

    What i did on the app.ts:

    //our root app component
    import {Component, OnInit} from 'angular2/core'
    
    @Component({
      selector: 'my-app',
      providers: [],
      template: `
        <div>
          <h2 [ngClass]="{'red-heading':isAlertOn, 'blue-heading':!isAlertOn}">Hello {{name}}</h2>
        </div>
      `,
      directives: []
    })
    export class App {
      isAlertOn:boolean;
    
      constructor() {
        this.name = 'Angular2';
        this.isAlertOn = false;
        this.setAlert();
      }
    
      ngOnInit() {
       // this.setAlert(); //this works the same way
      }
    
      setAlert(){ 
        let component = this;
    
        setTimeout(function(){
          console.log("in here");
          component.isAlertOn = true;
        },2000);
      };
    
    }