2017-02-10 87 views
-1

我有以下代码...为什么我的Angular 2 * ngIf不能渲染直到函数完成?

// Pug Template 
.notification-header-area.layout-row.layout-align-center-center(*ngIf="notification.message != null", class="{{notification.color}}") 

// Inside angular component 
private onNotificationStart = (notification) => { 
     this.notification = notification; 
     console.log(this.myElement.nativeElement); 
     if (this.myElement.nativeElement.children.length > 0) { 
      // TODO: We should probably do this in a more reliable way in case the template changes. 
      let elm = this.myElement.nativeElement.children[0]; 
      if (notification.fontSize) elm.style.fontSize = notification.fontSize; 
      if (notification.colorBackground) elm.style.backgroundColor = notification.colorBackground; 
      if (notification.colorFont) elm.style.color = notification.colorFont; 
     } 
} 

的问题是,如果我在控制台上线调试,浏览器不显示通知DOM元素。 console.log语句在写出对象时也会丢失它。如果函数完成运行ngIf呈现自己,我看到预期的元素。是否有$超时等值或什么?我从Web套接字获取此事件,并尝试Trouble with *ngIf in Angular 2 (TypeScript),但它没有奏效。我也无法在我简单的插件(不使用网络套接字)中重新创建它,所以我仍在研究演示。

另外,如果我换在这样它的工作原理超时...

private onNotificationStart = (notification) => { 
    this.notification = notification; 
    setTimeout(() => { 
     console.log(this.myElement.nativeElement); 
     if (this.myElement.nativeElement.children.length > 0) { 
      // TODO: We should probably do this in a more reliable way in case the template changes. 
      let elm = this.myElement.nativeElement.children[0]; 
      if (notification.fontSize) elm.style.fontSize = notification.fontSize; 
      if (notification.colorBackground) elm.style.backgroundColor = notification.colorBackground; 
      if (notification.colorFont) elm.style.color = notification.colorFont; 
     } 
    }) 
    // if(notification){ 
    //  this.myElement.nativeElement.style.backgroundColor = 
    // } 
} 
+0

我不明白问题所在。预期的行为是什么? –

+1

为什么“* ngIf不能渲染直到函数完成”有问题? –

+0

这不具有相同的问题https://plnkr.co/edit/E2o56qn4el7cniofwvZK?p=preview所以我的不同是什么? – Jackie

回答

1

简短的回答:一切正常在这两种情况下。如果你的期望不同,那就错了。

的时间长一点......

你不能指望角度做一些魔术或比执行它的浏览器更聪明。 :)如果我们简化一点... Javascript总是只有一个执行线程(不考虑web工作者)。当你在你的函数中改变通知标志时,在你的函数完成之前,外界不会发生任何事情,因为它阻塞了唯一可用的执行线程。只有在此之后,稍后的某个时间点,更改检测才会启动,并执行所有视图同步,组件创建或销毁以及其他所有必须完成的操作。这就是为什么它可以与setTimeout()一起工作 - 它为所有这些事情发生提供了机会。

+0

为什么这不会有相同的问题呢,它应该是相似的,但这更多是我所期望的。 https://plnkr.co/edit/E2o56qn4el7cniofwvZK?p=preview – Jackie

+0

一切正常,因为它应该在这个片段以及。你似乎对你的期望有点困惑。 –

1

Angular2(和4)使用zone.js修补异步API,如addEventHandlersetTimeout,....每当一个事件或setTimeout或另一异步API调用发生,角运行变化检测的处理程序方法已经完成之后。更改检测会导致更新视图(绑定)。这也是当*ngIf得到更新。因此*ngIf在绑定变量被更新的方法结束后被更新,这正是预期的行为。

更新

回调可能是跑到外面Angulars区,因为网络套接字API可能无法通过zone.js覆盖。 您可以注入private zone:NgZone,敷代码

this.zone.run(() => wrapped code here) 

或注入private cdRef:ChangeDetectorRef,并呼吁

this.cdRef.detectChanges(); 

绑定字段进行了更新,以显式调用变化检测之后。

+0

如果我记得我的web套接字实验正确,它们被zone.js覆盖,所以没有必要将它包装到这样的东西中。重点在于OP将不得不使用setTimeout()。即使他在zone.run()内部运行了某些东西,也无济于事,因为角将继续等待ngZone中所有任务的完成,并且只有在此之后,它才会开始更改检测以及所有这些内容。 –