Angular 4 - “等待操作”的正确方法是什么? [英] Angular 4 - What is the right way to "wait for operation"?

查看:129
本文介绍了Angular 4 - “等待操作”的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个简单的问题,它有一个hacky解决方案 setTimeout(...,0)

查看这个简单的代码:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <input value='Fill Data' type='button' (click)='fill()'/>
      <span *ngFor="let o of Items" class='mySpan'>Span To Detect<br></span>
    </div>
  `,
})
export class App {
  Items:Array<number> = new Array<number>();

  fill()
  {
   this.Items = [1,2,3,4,5,6,7,8,9,10]
   this.analyzeDom(); //this has to run here
  }

  analyzeDom()
   {
      alert($("div .mySpan").length) // "0"

     //BUT if I set this hacky trick , it works
     // setTimeout(function (){  alert($("div .mySpan").length)},0) // "10"
   }
}

如果我点击按钮,警报显示0。我明白为什么会这样。这是因为Angular没有完成其循环来实际填充 ngFor

If I click the button , the alert shows "0". I understand why it's happening. It's becuase Angular didn't complete its cycle to actually populate the ngFor.

然而 - 用<做这个技巧code> setTimeout(..,0)对我来说似乎有些苛刻,我不想相信它。

However - doing this trick with setTimeout(..,0) seems a bit hacky to me and I prefer not to trust on it.

问题:

Angular中等待操作的正确方法是什么? (所以我会看到10)?

What is the right way to "wait for operation" in Angular ? (so that I'll see "10") ?

Plnkr

推荐答案

1)您可以强制Angular更新DOM通过调用 cdRef.detectChanges

1) You can force Angular to update the DOM by calling cdRef.detectChanges

constructor(private cdRef: ChangeDetectorRef) {}

analyzeDom(){
  this.cdRef.detectChanges();
  alert($("div .mySpan").length)

< a href =http://plnkr.co/edit/XFlV5saTLtiNT8QPOlCO?p=preview =nofollow noreferrer> Plunker

Plunker

因为 setTimeout 是macrotask因此它正在运行下一个摘要周期。
这意味着在调用 setTimeout 之后,将检查所有组件树

As setTimeout is macrotask therefore it is running next digest cycle. It means that after calling setTimeout all components tree will be checked

cdRef.detectChanges 不会调用 appRef.tick()。它只执行变更检测组件本身及其子项。

cdRef.detectChanges doesn't call appRef.tick(). It only executes change detection component itself and its children.

2)或者您可以等到Angulat通过订阅 zone.onMicrotaskEmpty来更新DOM / code>

2) or you can wait until Angulat has updated DOM by subscribing to zone.onMicrotaskEmpty

import 'rxjs/add/operator/first';

constructor(private zone: NgZone) {}
...
this.zone.onMicrotaskEmpty.first().subscribe(() => this.analyzeDom());

注意:第一个操作符可能导致内存泄漏。请参阅 https://github.com/angular/material2/issues/6905

订阅 onMicrotaskEmpty 不会调用更改检测周期

Subscribing to onMicrotaskEmpty doesn't call change detection cycle

< a href =http://plnkr.co/edit/1MS3w4GP7zv5tYZD2hn8?p=preview =nofollow noreferrer> Plunker

Plunker

这篇关于Angular 4 - “等待操作”的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆