web-dev-qa-db-ja.com

Angular 5タイムアウト後にビューが更新されない

Angular 5:でしばらくしてから要素を非表示にするタイムアウトを設定しています。

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

ただし、これはビューを更新しません。 console.logは出力を提供するので、タイムアウトは確実に機能します。

Angularjsでは、$applyダイジェストを開始するため、Angular 5の同等の方法を見つける必要があると推測しています。

12
Peter

setTimeoutコールバックは、「showElement」変数のスコープを失うと思います。

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

矢印関数を使用する必要があります。

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

または、bindを使用します。

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

setTimeoutコールバック関数に適切なコンテキストを渡すため。

32

更新:修正された回答。

他の人が正しく答えているので、変更が反映されない理由は、this参照への誤った参照のためです。

function() { ... }表記を使用する場合、thisへの参照は関数自体のコンテキストであることに注意してください。そう

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);
}

上記をES6矢印表記に変更すると、this参照のコンテキストが親コンテキストに変更されます。そう

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

lexical thishere の詳細をご覧ください。

3
JeanPaul A.

関数スタイル「this」参照を使用すると、次のように動作しません。例は正しく動作します

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

Angular 7アプリで同じ問題に直面しました。ボタンのタイトルとアイコンのソースを変更する必要がありました。

<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);

  }

タイムアウト関数にthis.cd.markForCheck()を追加すると、私の場合の問題は解決しました。

以前、これは@artemisianによって Angular2でコメントされ、settimeout で変数が変更された後にビューが更新されませんでした

0