Ngxs - 如何链接操作?
Ngxs - How do I chain actions?
我想为我的注册做这样的事情。
点击注册按钮时,会执行:
this.store.dispatch(new Register(user))
.subscribe(response => {
localStorage.setItem('token', JSON.stringify(response.token));
let redirectUrl = this.store.dispatch(new RegisterSuccess(response));
if (redirectUrl) {
this.router.navigate([redirectUrl]);
} else {
this.router.navigate(['/home']);
}
}, error => {
this.store.dispatch(new RegisterFailed());
});
州:
@Action(Register)
register({ patchState }: StateContext<AuthenticationStateModel>, { payload }: Register) {
patchState({
isLoading: true
});
return this.authenticationService.register(payload);
}
@Action(RegisterFailed)
registerFailed({ patchState }: StateContext<AuthenticationStateModel>) {
patchState({
isLoading: false
});
}
@Action(RegisterSuccess)
registerSuccess(sc: StateContext<AuthenticationStateModel>, { payload }: RegisterSuccess) {
sc.patchState({
user: payload.user,
token: payload.token,
isAuthenticated: true,
isLoading: false,
});
return sc.getState().redirectUrl;
}
1) 我希望注册操作 return 来自 http 请求的 Observable。
2)然后订阅它,如果请求成功,则触发 RegisterSuccess(我希望它成为 return 来自状态的项目)。如果请求失败,则触发 RegisterFailed。
我实际上已经通过将相同的代码放入状态(对 c 进行了少量修改)来完成它,但我觉得它太混乱而且不是正确的方法所以将它放在组件中但我可以'不要让它再次工作。
我是这样做的:
- 当用户执行一个动作时,只需发送动作参数(如果有的话),例如
new MyAction()
。一般来说,不需要订阅这个调度的动作,我发现它也让代码看起来很乱。
@Action
函数处理内容并可选地调度 success/failed 操作(例如 MyActionSuccess
、MyActionFailed
或其他一些有意义的操作)。如果此操作只能有一个结果,则无需发送成功 - 此操作的完成即为成功。
- 为了处理成功(等...)执行的操作,我订阅了 action handlers 以获取 routing/redirection 内容。这些将由组件根据组件的生命周期subscribed/unsubscribed。 (例如
ngOnInit()
、ngOnDestroy()
)。
老实说,我不知道这是不是正确的或最好的方法,我现在就是这样做的。
docs建议您进行以下操作:
对于同步操作:
return ctx.dispatch(new TakeAnimalsOutside());
对于异步操作:
return this.animalService.feed(action.animalsToFeed).pipe(
mergeMap(() => ctx.dispatch(new TakeAnimalsOutside()))
dispatch
的有趣之处在于您可以
dispatch([new Action1(), new Action2(), ...etc])
你可以使用concatMap
它是rxjs
运算符
example.pipe(
concatMap(() => this.store.dispatch(new FirstAction())),
concatMap(() => this.store.dispatch(new SecondAction())),
concatMap(() => this.selectorDependOnAction$)).subscribe((res) => {
//anything you want to do it
});
}
concatMap
的一些资源
我想为我的注册做这样的事情。
点击注册按钮时,会执行:
this.store.dispatch(new Register(user))
.subscribe(response => {
localStorage.setItem('token', JSON.stringify(response.token));
let redirectUrl = this.store.dispatch(new RegisterSuccess(response));
if (redirectUrl) {
this.router.navigate([redirectUrl]);
} else {
this.router.navigate(['/home']);
}
}, error => {
this.store.dispatch(new RegisterFailed());
});
州:
@Action(Register)
register({ patchState }: StateContext<AuthenticationStateModel>, { payload }: Register) {
patchState({
isLoading: true
});
return this.authenticationService.register(payload);
}
@Action(RegisterFailed)
registerFailed({ patchState }: StateContext<AuthenticationStateModel>) {
patchState({
isLoading: false
});
}
@Action(RegisterSuccess)
registerSuccess(sc: StateContext<AuthenticationStateModel>, { payload }: RegisterSuccess) {
sc.patchState({
user: payload.user,
token: payload.token,
isAuthenticated: true,
isLoading: false,
});
return sc.getState().redirectUrl;
}
1) 我希望注册操作 return 来自 http 请求的 Observable。
2)然后订阅它,如果请求成功,则触发 RegisterSuccess(我希望它成为 return 来自状态的项目)。如果请求失败,则触发 RegisterFailed。
我实际上已经通过将相同的代码放入状态(对 c 进行了少量修改)来完成它,但我觉得它太混乱而且不是正确的方法所以将它放在组件中但我可以'不要让它再次工作。
我是这样做的:
- 当用户执行一个动作时,只需发送动作参数(如果有的话),例如
new MyAction()
。一般来说,不需要订阅这个调度的动作,我发现它也让代码看起来很乱。 @Action
函数处理内容并可选地调度 success/failed 操作(例如MyActionSuccess
、MyActionFailed
或其他一些有意义的操作)。如果此操作只能有一个结果,则无需发送成功 - 此操作的完成即为成功。- 为了处理成功(等...)执行的操作,我订阅了 action handlers 以获取 routing/redirection 内容。这些将由组件根据组件的生命周期subscribed/unsubscribed。 (例如
ngOnInit()
、ngOnDestroy()
)。
老实说,我不知道这是不是正确的或最好的方法,我现在就是这样做的。
docs建议您进行以下操作:
对于同步操作:
return ctx.dispatch(new TakeAnimalsOutside());
对于异步操作:
return this.animalService.feed(action.animalsToFeed).pipe(
mergeMap(() => ctx.dispatch(new TakeAnimalsOutside()))
dispatch
的有趣之处在于您可以
dispatch([new Action1(), new Action2(), ...etc])
你可以使用concatMap
它是rxjs
运算符
example.pipe(
concatMap(() => this.store.dispatch(new FirstAction())),
concatMap(() => this.store.dispatch(new SecondAction())),
concatMap(() => this.selectorDependOnAction$)).subscribe((res) => {
//anything you want to do it
});
}
concatMap