8

Angular 2 コンポーネントを作成していますが、特定の Observable パターンを使用すると、Angular の変更検出が機能しません。次のようになります。

    let getResult$ = this.http.get('/api/identity-settings');

    let manager$ = getResult$
        .map((response) => /* -- create manager object -- */);

    let signinResponse$ = manager$
        .flatMap(manager => manager.processSigninResponse());

    this.readyToLogin$ = manager$.map(() => true).startWith(false);
    this.isLoggedIn$ = signinResponse$.map(() => true).startWith(false);

次に、私のテンプレートで:

<h1>Ready to Log In: {{readyToLogin$ | async}}</h1>
<h1>Logged In: {{isLoggedIn$ | async}}</h1>

Observable は、readyToLogin$に応答して発生する一連の同期操作に基づいているためhttp.get()(Angular の「モンキー パッチ」は、いつ変更を検出する必要があるかを確実に認識できるようにします)、「ログイン準備完了」メッセージtrueは適切なタイミングで切り替わります。 .

ただし、 がprocessSignInResponse()生成されるPromise<>ため、 の結果にサブスクライブするものはすべてflatMap、http 要求の完了イベントとは非同期に発生します。したがって、変更を確認する必要があることをコンポーネントのゾーンに通知するには、手動で介入する必要があります。

サブスクリプションが解決された後に変更を検出するsignInResponse$ことを知っている方法でオブザーバブルをラップするにはどうすればよいですか?NgZone

アップデート

ブランドンの答えは、RC5に更新するまで機能し、その時点で再び機能しなくなりました。私が使用していたサードパーティのライブラリは、 Zone.js を使用していないことがわかりました。それが解決されれば、回避策を使用する必要はまったくありませんでした。ビルトインのモンキー パッチが機能しました。

4

3 に答える 3

8

observeOnZone任意のオブザーバブルを「モンキー パッチ」するために使用できる新しいオペレーターを作成できます。何かのようなもの:

Rx.Observable.prototype.observeOnZone = function (zone) {
    return Observable.create(observer => {
        var onNext = (value) => zone.run(() => observer.next(value));
        var onError = (e) => zone.run(() => observer.error(e));
        var onComplete = () => zone.run(() => observer.complete());
        return this.subscribe(onNext, onError, onComplete);
    });
};

そして、次のように使用します。

this.isLoggedIn$ = signinResponse$.map(() => true).startWith(false).observeOnZone(zone);
于 2016-06-02T15:58:15.457 に答える
2

を使用してコードをAngularsゾーンに強制できますzone.run()

constructor(private zone:NgZone) {}

someMethod() {
  signinResponse$.subscribe(value => {
    zone.run(() => doSomething());
  });
}
于 2016-06-02T14:56:28.887 に答える