bal*_*teo 16 ngrx ngrx-effects
我遇到了ngrx商店的问题,没有调度一个应该处理它的效果的动作.
以下是尝试发送的组件:
signin() {
this.formStatus.submitted = true;
if (this.formStatus.form.valid) {
this.store.dispatch(new StandardSigninAction(this.formStatus.form.value.credentials));
}
}
Run Code Online (Sandbox Code Playgroud)
行动:
export const ActionTypes = {
STANDARD_SIGNIN: type('[Session] Standard Signin'),
LOAD_PERSONAL_INFO: type('[Session] Load Personal Info'),
LOAD_USER_ACCOUNT: type('[Session] Load User Account'),
RELOAD_PERSONAL_INFO: type('[Session] Reload Personal Info'),
CLEAR_USER_ACCOUNT: type('[Session] Clear User Account')
};
export class StandardSigninAction implements Action {
type = ActionTypes.STANDARD_SIGNIN;
constructor(public payload: Credentials) {
}
}
...
export type Actions
= StandardSigninAction
| LoadPersonalInfoAction
| ClearUserAccountAction
| ReloadPersonalInfoAction
| LoadUserAccountAction;
Run Code Online (Sandbox Code Playgroud)
效果:
@Effect()
standardSignin$: Observable<Action> = this.actions$
.ofType(session.ActionTypes.STANDARD_SIGNIN)
.map((action: StandardSigninAction) => action.payload)
.switchMap((credentials: Credentials) =>
this.sessionSigninService.signin(credentials)
.map(sessionToken => {
return new LoadPersonalInfoAction(sessionToken);
})
);
Run Code Online (Sandbox Code Playgroud)
我可以在调试中看到组件确实调用了调度方法.我还可以确认StandardSigninAction确实已实例化,因为构造函数中的断点被命中.
但standardSignin$效果并未被称为......
什么可能导致效果不被调用?
如何调试商店内发生的事情?
有人可以帮忙吗?
PS我在我的导入中运行以下效果如下:
EffectsModule.run(SessionEffects),
Run Code Online (Sandbox Code Playgroud)
编辑:这是我的SessionSigninService.signin方法(确实返回一个Observable)
signin(credentials: Credentials) {
const headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'});
const options = new RequestOptions({headers: headers});
const body = 'username=' + credentials.username + '&password=' + credentials.password;
return this.http.post(this.urls.AUTHENTICATION.SIGNIN, body, options).map(res => res.headers.get('x-auth-token'));
}
Run Code Online (Sandbox Code Playgroud)
car*_*ant 16
这不是一个明确的答案,但是,希望它会有所帮助.
在你开始之前:
@ngrx软件包(适用于您正在使用的Angular版本).如果你还没有这样做,你应该看一下 - 的实现Store - 这样你就可能出错的地方做了一些有根据的猜测.注意,Store它很轻.它既是可观察的(使用状态作为其源),也是观察者(遵循调度程序).
如果你看看store.dispatch你会看到它的一个别名
store.next,它调用next的Dispatcher.
所以打电话:
this.store.dispatch(new StandardSigninAction(this.formStatus.form.value.credentials));
Run Code Online (Sandbox Code Playgroud)
应该只看到调度员发出的动作.
Actions注入效果的可观察物也非常清晰.它只是一个使用它Dispatcher作为源的可观察对象.
要查看流经效果的动作,可以替换为:
@Effect()
standardSignin$: Observable<Action> = this.actions$
.ofType(session.ActionTypes.STANDARD_SIGNIN)
Run Code Online (Sandbox Code Playgroud)
有了这个:
@Effect()
standardSignin$: Observable<Action> = this.actions$
.do((action) => console.log(`Received ${action.type}`))
.filter((action) => action.type === session.ActionTypes.STANDARD_SIGNIN)
Run Code Online (Sandbox Code Playgroud)
ofType不是运营商; 这是一种方法,所以要添加do基于日志的记录,需要将其替换为filter.
记录到位后,如果您正在接收操作,则效果的实现会出现问题(或者动作类型的字符串/常量可能不是您认为的那样,并且某些内容不匹配).
如果效果没有收到派遣的动作,最可能的解释是store你派遣的StandardSigninAction那个与store你的效果所使用的不一样- 也就是说,你有一个DI问题.
如果是这种情况,你应该看看SessionEffects你说的工作有什么不同.(至少你有一些工作,这是一个开始试验的好地方.)他们是从一个不同的模块发送的吗?调度StandardSigninAction功能模块的模块是?
如果您破解其中一个工作SessionEffects来替换其已发送的操作,会发生StandardSigninAction什么?效果会运行吗?
请注意,本答案末尾的问题不是我想要回答的问题; 他们是你应该问自己和调查的问题.
您的商店的流可能因为未处理的错误而停止 - 或者可能更容易混淆 - 似乎使用"处理"的错误.catch实际上会杀死流而不重新发出新的Observable以保持正常运行.
例如,这将终止流:
this.actions$
.ofType('FETCH')
.map(a => a.payload)
.switchMap(query => this.apiService.fetch$(query)
.map(result => ({ type: 'SUCCESS', payload: result }))
.catch(err => console.log(`oops: ${err}`))) // <- breaks stream!
Run Code Online (Sandbox Code Playgroud)
但这将使事情保持活力:
this.actions$
.ofType('FETCH')
.map(a => a.payload)
.switchMap(query => this.apiService.fetch$(query)
.map(result => ({ type: 'SUCCESS', payload: result }))
.catch(e => Observable.of({ type: 'FAIL', payload: e}))) // re-emit
Run Code Online (Sandbox Code Playgroud)
对于任何rxjs Observable btw都是如此,这对于向多个观察者广播时尤其重要(如ngrx存储在内部使用内部Subject).
我使用的是更高版本的 ngrx (7.4.0),所以 carant 的建议是:
.do((action) => console.log(`Received ${action.type}`))
Run Code Online (Sandbox Code Playgroud)
应该...
... = this.actions.pipe(
tap((action) => console.log(`Received ${action.type}`)),
...
Run Code Online (Sandbox Code Playgroud)
最后我发现我没有将我的新效果导出添加到模块中,例如:
EffectsModule.forRoot([AuthEffects, ViewEffects]), // was missing the ', ViewEffects'
Run Code Online (Sandbox Code Playgroud)
小智 6
如果您使用的是版本 8,请确保将每个操作都用createEffect.
例子:
Create$ = createEffect(() => this.actions$.pipe(...))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11332 次 |
| 最近记录: |