Angular 5 View Not Updating After Timeout

2019-04-05 16:53发布

I'm setting a timeout to hide an element after a while in Angular 5:

this.showElement = true;
setTimeout(function () {
  console.log('hide');
  this.showElement = false;
}, 2000);

However, this doesn't update the view. The console.log gives me an output, so the timeout definitely works.

I have found that in Angularjs you needed to call $apply in order to start a digest, so I'm guessing I just need to find the Angular 5 equivalent way of doing that.

4条回答
男人必须洒脱
2楼-- · 2019-04-05 17:01

when you use function style "this" reference is not working do it like following and your example will work correctly

this.showElement = true;
setTimeout(() => {
    console.log('hide');
    this.showElement = false;
}, 2000);
查看更多
The star\"
3楼-- · 2019-04-05 17:15

Updated: Corrected answer.

As the others has correctly answered, the reason why the changes are not being reflected is because of the incorrect reference to the this reference.

Note that when using the function() { ... } notation, the reference to this is the context of the function itself. So

myFunction() {
    this.showElement = true;
    setTimeout(function() {
      console.log(this.showElement); // Will result in undefined;
      this.showElement = false; // Here, this, reference to context of the function wrapper
    }, 2000);
}

Changing the above to ES6 arrow notation, changes the context of the this reference to the parent context. So

myFunction() {
    this.showElement = true;
    setTimeout(() => {
      console.log(this.showElement); // Will result in true;
      this.showElement = false; // Here, value is updated
    }, 2000);
}

Read more about the lexical this here.

查看更多
疯言疯语
4楼-- · 2019-04-05 17:17

I think setTimeout callback lose scope to a variable "showElement".

this.showElement = true; // this - is in component object context
setTimeout(function () {
   console.log('hide');
   this.showElement = false; // here... this has different context
}, 2000);

You should use arrow function:

this.showElement = true;
setTimeout(() => {
  console.log('hide');
  this.showElement = false;
}, 2000);

Or use bind:

this.showElement = true;
setTimeout(function() {
  console.log('hide');
  this.showElement = false;
}.bind(this), 2000);

to pass context to setTimeout callback function.

查看更多
趁早两清
5楼-- · 2019-04-05 17:25

I faced the same problem in my Angular 7 app. I had to change the source of title and icon in button:

<button class="btn btn--outline-red text-uppercase font-weight-normal product-action-btn mt-3"
              (click)="addToCart()">
              {{addToCartProps.title}}
              <img style="width:15px; height:15px;" [src]="addToCartProps.src">
            </button>

.......

  addToCartProps = { title: 'Add to Cart', src: '' }

  addToCart() {

    this.addToCartProps.title = 'Adding';
    this.addToCartProps.src = 'assets/images/preloader-white.svg';

    setTimeout(() => {
      this.addToCartProps.title = 'Added';
      this.addToCartProps.src = 'assets/images/checked-icon-white.svg';
      this.cd.markForCheck();
      console.log('timeout 1 ', this.addToCartProps);
    }, 1000);

    setTimeout(() => {
      this.addToCartProps.title = 'Add to cart';
      this.addToCartProps.src = '';
      this.cd.markForCheck();
      console.log('timeout 2 ', this.addToCartProps);
    }, 1500);

  }

Adding this.cd.markForCheck() in timeout function solved the problem in my case.

Earlier this was also commented by @artemisian in Angular2, view not updating after variable changes in settimeout

查看更多
登录 后发表回答