如何完成2个http请求,然后触发另一个Action合并结果
How to complete 2 http requests and then trigger another Action to merge the results
我在 2 个不同的数据库中存储了相同的数据类型。
- 在 SQL 数据库 中,我存储了所有食物的大量列表。
- 在 Mongo 数据库中 我正在存储一个人的食物数据,这将
覆盖提供的默认食物数据。
两种类型的数据都将存储在我的 ngrx 存储应用程序状态和合并状态中。
export interface ApplicationState {
allSQLFoodData: FoodData;
allUserFoodData: FoodData;
mergedFoodData: FoodData;
}
我需要做的是从后端获取 allSQLFoodData
和 allUserFoodData
,将这些值存储到状态,并将两组数据合并到合并状态。
我通过 dispatch()
执行一个操作 INITIALIZE_DATA_ACTION
来完成此操作,然后我会在效果服务中收听该操作。
这是我在效果服务中的立场:
初始化数据效果-service.ts
@Injectable()
export class InitializeDataEffectService {
@Effect() initialize$: Observable<Action> = this.actions$
.ofType(INITIALIZE_DATA_ACTION)
.switchMap( (action) => {
return Observable.combineLatest(
this.foodService.loadSQLFoods( action.payload ),
this.userDataService.loadUserData( action.payload )
)
})
.switchMap(([allSQLFoodData, allUserData]) => {
return Observable.of(
new SQLFoodsLoadedAction( allSQLFoodData ),
new UserDataLoadedAction( allUserData ),
new BuildMergedFoodDataAction({sql: allSQLFoodData, user: allUserData})
)
})
constructor( private actions$: Actions, private foodService: FoodService, private userDataService: UserDataService ) {
}
}
如您所见,我正在侦听类型为 INITIALIZE_DATA_ACTION
的操作,并使用来自 http
响应的 combineLatest()
创建一个组合可观察对象。然后我调用 Action 类 为每个设置应用程序状态:
.switchMap(([allSQLFoodData, allUserData]) => {
return Observable.of(
new SQLFoodsLoadedAction( allSQLFoodData ),
new UserDataLoadedAction( allUserData ),
new BuildMergedFoodDataAction({sql: allSQLFoodData, user: allUserData})
)
})
但这给出了以下错误:
The type argument for type parameter 'T' cannot be inferred from the
usage. Consider specifying the type arguments explicitly. Type
argument candidate 'SQLFoodsLoadedAction' is not a valid type argument
because it is not a supertype of candidate 'UserDataLoadedAction'.
Types of property 'payload' are incompatible.
Type 'AllUserData' is not assignable to type 'AllSQLFoodData'.
Property 'foods' is missing in type 'AllUserData'.
我不确定如何
specifying the type arguments explicitly
即使我这样做了,我也不确定 Effect()
装饰器现在如何将结果分配给适当的状态值。 我怎样才能做到这一点?
到 return 来自 switchMap
的可观察对象,它从效果中发出多个动作,使用 Observable.from
,它可以接受一个数组:
import 'rxjs/add/observable/from';
import 'rxjs/add/operator/concatMap';
...
.concatMap(([allSQLFoodData, allUserData]) => Observable.from([
new SQLFoodsLoadedAction( allSQLFoodData ),
new UserDataLoadedAction( allUserData ),
new BuildMergedFoodDataAction({sql: allSQLFoodData, user: allUserData})
]))
请注意,switchMap
是不必要的,因为 returned 可观察对象将立即发出。您可以只使用 concatMap
,而不是。
此外,效果不会为状态分配任何内容。它的唯一作用是发出动作。这些操作将由 reducers 处理,reducers 将更新应用程序状态的适当部分。
我在 2 个不同的数据库中存储了相同的数据类型。
- 在 SQL 数据库 中,我存储了所有食物的大量列表。
- 在 Mongo 数据库中 我正在存储一个人的食物数据,这将 覆盖提供的默认食物数据。
两种类型的数据都将存储在我的 ngrx 存储应用程序状态和合并状态中。
export interface ApplicationState {
allSQLFoodData: FoodData;
allUserFoodData: FoodData;
mergedFoodData: FoodData;
}
我需要做的是从后端获取 allSQLFoodData
和 allUserFoodData
,将这些值存储到状态,并将两组数据合并到合并状态。
我通过 dispatch()
执行一个操作 INITIALIZE_DATA_ACTION
来完成此操作,然后我会在效果服务中收听该操作。
这是我在效果服务中的立场:
初始化数据效果-service.ts
@Injectable()
export class InitializeDataEffectService {
@Effect() initialize$: Observable<Action> = this.actions$
.ofType(INITIALIZE_DATA_ACTION)
.switchMap( (action) => {
return Observable.combineLatest(
this.foodService.loadSQLFoods( action.payload ),
this.userDataService.loadUserData( action.payload )
)
})
.switchMap(([allSQLFoodData, allUserData]) => {
return Observable.of(
new SQLFoodsLoadedAction( allSQLFoodData ),
new UserDataLoadedAction( allUserData ),
new BuildMergedFoodDataAction({sql: allSQLFoodData, user: allUserData})
)
})
constructor( private actions$: Actions, private foodService: FoodService, private userDataService: UserDataService ) {
}
}
如您所见,我正在侦听类型为 INITIALIZE_DATA_ACTION
的操作,并使用来自 http
响应的 combineLatest()
创建一个组合可观察对象。然后我调用 Action 类 为每个设置应用程序状态:
.switchMap(([allSQLFoodData, allUserData]) => {
return Observable.of(
new SQLFoodsLoadedAction( allSQLFoodData ),
new UserDataLoadedAction( allUserData ),
new BuildMergedFoodDataAction({sql: allSQLFoodData, user: allUserData})
)
})
但这给出了以下错误:
The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'SQLFoodsLoadedAction' is not a valid type argument because it is not a supertype of candidate 'UserDataLoadedAction'. Types of property 'payload' are incompatible. Type 'AllUserData' is not assignable to type 'AllSQLFoodData'. Property 'foods' is missing in type 'AllUserData'.
我不确定如何
specifying the type arguments explicitly
即使我这样做了,我也不确定 Effect()
装饰器现在如何将结果分配给适当的状态值。 我怎样才能做到这一点?
到 return 来自 switchMap
的可观察对象,它从效果中发出多个动作,使用 Observable.from
,它可以接受一个数组:
import 'rxjs/add/observable/from';
import 'rxjs/add/operator/concatMap';
...
.concatMap(([allSQLFoodData, allUserData]) => Observable.from([
new SQLFoodsLoadedAction( allSQLFoodData ),
new UserDataLoadedAction( allUserData ),
new BuildMergedFoodDataAction({sql: allSQLFoodData, user: allUserData})
]))
请注意,switchMap
是不必要的,因为 returned 可观察对象将立即发出。您可以只使用 concatMap
,而不是。
此外,效果不会为状态分配任何内容。它的唯一作用是发出动作。这些操作将由 reducers 处理,reducers 将更新应用程序状态的适当部分。