web-dev-qa-db-ja.com

ngrxの使用中にディスパッチが完了した後にコードを実行する

私のサンプルAngular 2 application)では、状態管理にngrx/storeおよびngrx/effectsを使用しています。

以下は、新しいアイテムを追加するコンポーネントの関数の1つです。

addAuthor() {

    this.store.dispatch(addAuthorAction(this.fg.value));
    console.log('2')        
} 

上記のコードで「this.store.dispatch(addAuthorAction(this.fg.value));」 AJAXサーバーへの呼び出しを行い、新しい作者をデータベースに追加します。これは正常に機能しています。

そして、「this.store.dispatch(addAuthorAction(this.fg.value));」だからです。非同期アクションです。AJAX呼び出しが完了する前でもconsole.log( "2")ステートメントが実行されます。

私の質問は、store.dispatchが完了した後にconsole.logが実行されるように何を変更する必要があるかです。

8
refactor

簡単な答え:できません。

あなたが言ったように、dispatchは非同期です。

あなたがすべきことは @ ngrx/effects を使うことです。 addAuthorActionを使用するのとほぼ同じですが、関数を呼び出す代わりに、ディスパッチされたアクションを「キャッチ」し、レデューサーによって適用された直後に何かを実行します。

だから私が一般的にしたいのは、私が私の行動を3つに分割することです、例えば:-FETCH_USER-FETCH_USER_SUCCESS-FETCH_USER_ERROR

  • FETCH_USERは、ブール値を切り替えるために使用されているため、ユーザーをフェッチしながらスピナーを表示できます
  • エフェクトからこのアクションをキャッチし、httpリクエストを行ってユーザーをフェッチします

  • Http応答に問題がなく、探している情報がある場合は、エフェクトからディスパッチしますFETCH_USER_SUCCESS応答をペイロードとして、それ以外の場合はFETCH_USER_ERRORと私はブール値をfalseに切り替えます(たとえば、もう一度フェッチしようとすることができます)。

したがって、あなたの例では、console.log FETCH_USER_SUCCESSの後の何か、別のエフェクトを使用してFETCH_USER_SUCCESSをキャッチし、ここでやりたいことを行います。

7
maxime1992

Ngrxを使用すると、次のようなアクションを聞くことができます。

constructor(private actionsSubject$: ActionsSubject, private store: Store<AppState>) {}

ngOnInit() {
  this.actionsSubject$.pipe(
    takeUntil(this.unsubscribe$), // optional
    filter((action) => action.type === SimsActionTypes.SimEditedSuccess)
  ).subscribe(({payload}) => {
    console.log(payload)
  )

}

FIRST_ACTIONをディスパッチするときは、エフェクトを使用してHTTPリクエストを作成します。実際には、レスポンスが返ってきたら、レスポンスをペイロードとしてSECOND_ACTIONを起動します。次に、コントローラーの.tsファイルでSECOND_ACTIONをリッスンします

5
danday74

テスト済み

"@ngrx/core": "^1.2.0",
"@ngrx/effects": "^7.4.0",
"@ngrx/router-store": "^7.4.0",
"@ngrx/store": "^7.4.0",
"@ngrx/store-devtools": "^7.4.0",

これも機能します:

import { ofType, Actions } from '@ngrx/effects';

// Constructor
constructor(
   private _actions$: Actions,
   private _store: Store<any>,
) { }

// YOUR METHOD    
this._store.dispatch(<ACTION>);
this._actions$.pipe(ofType(<ACTION_NAME>)).subscribe((data: any) => {
  console.log(data);  // returned state data        
})
0
techyaura