【问题标题】:Angular 5 View Not Updating After TimeoutAngular 5 View 超时后不更新
【发布时间】:2018-02-21 08:07:27
【问题描述】:

我在 Angular 5 中设置了一段时间后隐藏元素的超时时间:

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

但是,这不会更新视图。 console.log 给了我一个输出,所以超时肯定有效。

我发现在 Angularjs 中,您需要调用 $apply 才能开始摘要,所以我猜我只需要找到 Angular 5 的等效方法即可。

【问题讨论】:

  • 您不需要更改检测甚至超时,只需将 this.showElement 双向绑定到元素本身的 *NgIf ,它就会按需删除并显示它。当心超时使用,它可能会消耗资源,如果你想让它成为通用的,它会杀死你的应用程序。
  • 要添加的一点是,在 Angular 1.x 中,您可以使用 $timeout 服务。在 Angular 2+ 中,没有 $timeout 服务。在您希望保持组件/服务上下文的词法范围的地方,首选/推荐使用箭头函数。

标签: javascript angular asynchronous


【解决方案1】:

在您的构造函数中,添加一个更改检测器:

constructor(private cd: ChangeDetectorRef) {}

然后在你的 setTimeout 中:

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

【讨论】:

  • 有什么解释吗?
【解决方案2】:

更新:更正答案。

正如其他人已正确回答,未反映更改的原因是对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的信息。

【讨论】:

  • 在 Ionic 4 中遇到了同样的问题,这是正确的解决方案。
  • ? 你的答案是正确的,它不是关于 范围this 不是 范围。 ???
【解决方案3】:

我认为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 回调函数。

【讨论】:

    【解决方案4】:

    我在 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, view not updating after variable changes in settimeout 中也对此进行了评论

    【讨论】:

      【解决方案5】:

      当您使用函数样式“this”时,参考不起作用 像下面那样做,你的例子会正常工作

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

      【讨论】:

        【解决方案6】:

        它正在更新值,但问题是this。您可以通过绑定或箭头函数设置 this 的值。

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

        或者我们可以使用箭头函数,因为它的 this 值是包含函数的设置。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-04-07
          • 2019-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-25
          • 2018-03-11
          相关资源
          最近更新 更多