"异步"管未呈现流更新 [英] "async" pipe not rendering the stream updates

查看:177
本文介绍了"异步"管未呈现流更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图渲染窗口大小的窗口在角2组件利用一个异步通过管道流调整:

Trying to render the window size on window resize through a stream in an angular 2 component utilizing an async pipe:

< H2>尺寸:{{$大小|异步| JSON}}< / H>

const windowSize$ = new BehaviorSubject(getWindowSize());
Observable.fromEvent(window, 'resize')
  .map(getWindowSize)
  .subscribe(windowSize$);

function getWindowSize() {
  return {
    height: window.innerHeight,
    width: window.innerWidth
  };
}

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
      <h2>Size: {{size$ | async | json}}</h2>
    </div>
  `,
  directives: []
})
export class App {
  size$ = windowSize$.do(o => console.log('size:', o));
  constructor() {  }
}

但部分只呈现初始状态并忽略流更新。
如果你打开​​控制台,在窗口调整大小,你会看到来自同一数据流的更新。

But the component only renders the initial state and ignores the stream updates. If you open the console, on window resize, you'll see the updates from that same stream.

无法了解我在这里失踪。

Can't understand what i am missing here.

下面是一个 plunker

推荐答案

事件处理程序是角区外运行,因此角变化检测时不运行事件触发。把事件处理程序组件内,然后它会得到猴子修补与所有其他异步事件一起,因此,角度变化的检测将每个事件之后执行(和更新视图):

The event handler is running outside the Angular zone, so Angular change detection doesn't run when an event fires. Put the event handler inside your component and then it will get monkey-patched along with all of the other asynchronous events, hence Angular change detection will execute after each event (and update the view):

ngOnInit() {
    Observable.fromEvent(window, 'resize')
     .map(getWindowSize)
     .subscribe(windowSize$);
}

<大骨节病> Plunker

另一种选择,在评论中讨论的,是手动运行变化检测当一个视图模型更新:

Another option, discussed in the comments, is to manually run change detection when a view model is updated:

import {Component, ChangeDetectorRef} from 'angular2/core'
...
export class App {
  size$ = windowSize$.do(o => {
     console.log('size:', o);
     // since the resize event was not registered while inside the Angular zone,
     // we need to manually run change detection so that the view will update
     this._cdr.detectChanges();
  });

  constructor(private _cdr: ChangeDetectorRef) {}
}

<大骨节病> Plunker

请注意,你可能反而想尝试运行 ApplicationRef.tick()一次,说在你的根组件,这将在所有组件和ndash的运行变化检测;而不是在每个组件运行 ChangeDetectorRef.detectChanges()。 (您可能需要包装打勾() A 的setTimeout()方法内,以确保所有组件视图模型进行了更新......我不知道,当所有的做()回调方法将被执行 - 即如果他们的一圈都跑JavaScript的VM,或者多圈都有涉及。)

Note that you might instead want to try running ApplicationRef.tick() once, say in your root component, which will run change detection on all of the components – rather than running ChangeDetectorRef.detectChanges() in each component. (And you might need to wrap tick() inside a setTimeout() method, to ensure that all of the component view models were updated... I'm not sure when all of the do() callback methods will be executed -- i.e., if they all run in one turn of the JavaScript VM, or if multiple turns are involved.)

这篇关于&QUOT;异步&QUOT;管未呈现流更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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