Javascript 超时后 Angular 5 视图未更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48900860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:16:51  来源:igfitidea点击:

Angular 5 View Not Updating After Timeout

javascriptangularasynchronous

提问by Peter

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

我正在设置超时以在 Angular 5 中一段时间​​后隐藏元素:

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

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

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

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

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

回答by Krzysztof Raciniewski

I think the setTimeoutcallback lose a scope to the "showElement" variable.

我认为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);

You should use arrow function:

您应该使用箭头功能:

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

Or use bind:

或使用bind

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

to pass proper context to the setTimeoutcallback function.

将适当的上下文传递给setTimeout回调函数。

回答by JeanPaul A.

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 thisreference.

由于其他人已正确回答,因此未反映更改的原因是对参考的this引用不正确。

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

请注意,在使用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);
}

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

将上述更改为 ES6 箭头符号,将this引用的上下文更改为父上下文。所以

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 thishere.

阅读有关lexical this此处的更多信息。

回答by Matt

In your constructor, add a change detector:

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

constructor(private cd: ChangeDetectorRef) {}

And then in your setTimeout:

然后在你的setTimeout 中

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

回答by xelilof

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

当您使用函数样式“this”引用不起作用时,请执行以下操作,您的示例将正常工作

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

回答by Nodirabegimxonoyim

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

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

  }

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

在超时函数中添加this.cd.markForCheck()解决了我的问题。

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

早些时候,@artemisian 在Angular2 中也对此进行了评论,视图在 settimeout 中的变量更改后不更新