我正在使用Angular 6,ngrx / store。我有这样的效果,负责更新事物。取决于一些逻辑,我想派遣不同的行动。可以这样做吗?如果我使用map
@Effect()
dispathMultipleActions$ = this.actions$.pipe(
ofType(ActionTypes.UpdateSomething),
map(() => {
const actions: Action[] = [];
const array = [1, 2, 3, 4, 5];
array.forEach(item => {
if (item > 3) {
actions.push(new DeleteAction(item));
} else {
actions.push(new ChangeAction(item));
}
});
return actions;
})
);
的内容,有什么区别?有没有更好的方法来解决这个问题?
SignupForm
答案 0 :(得分:9)
效果会转换动作流,因此您可以将动作流作为输入和输出。在您的示例中,您将操作映射到操作数组。动作数组流不是有效的输出类型。您需要展平该数组,这意味着您不会将数组本身发送到输出流中,而是将其每个元素都发送出去。
而不是:
max
你应该这样做:
import json
lookup = ["CARDINALS", "BUFFALO", "DOLPHINS", "COWBOYS"]
url = 'api url'
data = requests.get(url)
team_data = json.loads(data.content)
new_teams = [i for i in team_data if i['team_id'] in lookup]
min_win = min(new_teams, key=lambda x:x['wins'])['wins']
max_win = max(new_teams, key=lambda x:x['wins'])['wins']
change_win = (max_win-min_win)/float(min_win+max_win)
要将Observable of数组展平为每个元素的Observable,您可以使用其中一个运算符input: --a-------a------>
output: --[b,c]---[b,c]-->
,input: --a-------a------>
output: --b-c-----b-c-->
,mergeMap
。在大多数情况下,switchMap
将是正确的选择。如果您想了解有关这些运算符的更多信息,请查看此answer。
exhaustMap
答案 1 :(得分:1)
我遇到过同样的情况(假设 NgRx 10 或更高版本),我有不同的观点,更基本的使用效果的方法。在一个地方依次触发多个动作,特别是在单个效果中,是反模式。 从本质上讲,保持动作和潜力减少的一致general flow of application state in NgRx 很重要。正如 NgRx 架构所预见的那样。
遵循 the 3 effect rules 已经有助于避免困难情况:
这样,它可以帮助您遵循 separation of concerns 设计模式,这当然也可以帮助您将 NgRx 效果变得更易于单元测试。
回到您的示例,您可以通过中间代理操作简单地分离您想要执行的操作(2 个附加操作)。
在您的情况下,除非出现特殊逻辑,否则您可能甚至不需要原始效果 dispathMultipleActions$。 (也许,它可能属于一个更易于单元测试的状态 Reducer)。
假设 ActionTypes.UpdateSomething 已经有一个数组有效负载对象,您可以将 dispathMultipleActions$ 拆分为单个对象,因此您可以执行以下操作:
@Effect()
deleteAction$ = this.actions$.pipe(
ofType(ActionTypes.UpdateSomething),
concatMap(from(new Promise((array) => {
array.forEach(item => {
if (item > 3) {
//do something
}
});
}))),
{dispatch: false}
);
@Effect()
changeAction$ = this.actions$.pipe(
ofType(ActionTypes.UpdateSomething),
concatMap(from(new Promise((array) => {
array.forEach(item => {
if (item <= 3) {
//do something
}
});
}))),
{dispatch: false}
);
答案 2 :(得分:0)
我在Ngrx 10中遇到了同样的问题,返回数组的解决方案似乎不再起作用...
我的解决方案是使用this.store$.dispatch( myAction(...) )
`
mergeMap((action: RegisterRequest) => {
// check for register request success
// for all actions from 0 to (last -1), use a dispatch() :
this.store$.dispatch( RegisterSuccess() );
// and the last action is returned:
return LoginRequest(action.payload);
})