RXJS を使用して簡単な TODO アプリケーションを作成しようとしています。 TODOタスクを含むJSONサーバーモックデータベースがあります。
したがって、私はこの TasksService を使用することになりました:
リーリータスクを追加するときに、すぐにサーバーに公開したくありません。 したがって、サーバーからタスクを取得したら、それを _tasks プロパティに保存し、 _tasks$:BehaviorSubject の next() メソッドに渡します。 後でタスクをサーバーにバッチパブリッシュしたいので、今度はそれらを Angular で正しく表示したいだけだからです。
AppComponent でタスクを取得し、タスク プロパティに割り当てます。
リーリー私の HTML テンプレートでは、タスク属性として非同期パイプを使用し、タスクを表示します:
リーリーしかし、TaskService で次の行を誤って削除してしまいました。
this._tasks$.next(this._tasks);
したがって、私のメソッドは次のようになります:
リーリーただし、タスクの追加は引き続き有効です。新しいタスクの配列を BehaviorSubject に渡さなくても、Angular には新しく追加されたタスクが表示されます。
そこで、タスクに値を記録することにしました。 : AppComponent クラスの BehaviorSubject<ITask[]> プロパティ:
リーリーおよびタスクは期待どおりに追加されます - 1 つのタスクを含む配列を取得するたびに:
リーリーしかし、この行を TaskService の addTask メソッドに返すと、次のようになります。
this._tasks$.next(this._tasks);
次のログを取得します:
リーリーそれで、なぜ Observable がこのように動作するのかについて少し迷っています...おそらく next() メソッドを完全には理解していませんか?
私が理解している限り、このコードには 2 つの問題があります。まず、コンソール ログがなぜ重複するのかわかりません。次に、動作サブジェクトで「.next()」を呼び出していないにもかかわらず、ビューが更新された理由がわかりません。
最初のものから始めましょう。
rxjs オブザーバブルと BehaviorSubject がどのように機能するかを理解する必要があります。 通常の Observable は、サブスクライブすると、特定の値が発行されるまで待機し、その値が発行されるたびに、それにアタッチしたオペレーションを呼び出します。例えば:### リーリー
このコードでは、ngOnInit で 1 回だけサブスクライブしていることに注意してください。それにもかかわらず、(ボタンなどから) EmitValue() メソッドが呼び出されるたびに、console.log が呼び出されます。これは、購読が解除されるまで購読が継続されるためです。これは、トピックに対して next() が呼び出されるたびに操作が呼び出されることを意味します。トピックを 3 回サブスクライブしましたが、値が出力されるたびにコンソール ログが 3 回呼び出されるようになりました。これは、作成するサブスクリプションごとに呼び出されます。
ここで例を見てみると、addTask ボタンがクリックされるたびにサブスクリプションが追加されます。そのため、タスクを追加するたびに追加のコンソール ログが作成されます。 しかし、最初の例では、.next() を削除すると、値を出力していないにもかかわらず、いくつかのコンソール ログが記録されます。これはなぜでしょうか?ここで、BehaviorSubject に移ります。これは、その値を保持し、サブスクライブするとすぐに発行される特別なテーマです。また、.next() を呼び出すたびに出力されますが、それは行わないため、サブスクライブするたびに 1 つのコンソール ログが呼び出されます。
あなたがすべきことは電話です
リーリーngOnInit() などで 1 回のみ
さて、第二期に入りますこれは非常に簡単ですが、参照がどのように機能するかについてある程度の知識が必要です。
サービスでは、タスク配列全体を BehaviorSubject に配置します。実際、このサブジェクトはこの配列への参照を保持しています。これは、新しい値を配列にプッシュするたびに、BehaviorSubject もその値を所有することを意味します。これは、addTask メソッドを呼び出すたびに、新しい値がタスク配列にプッシュされ、BehaviorSubject にもその値が設定されるときに起こることです。