私のサンプル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が実行されるように何を変更する必要があるかです。
簡単な答え:できません。
あなたが言ったように、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をキャッチし、ここでやりたいことを行います。
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をリッスンします
テスト済み
"@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
})