从组件分派动作时未调用ngrx效果 [英] ngrx effect not being called when action is dispatched from component

查看:64
本文介绍了从组件分派动作时未调用ngrx效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在ngrx商店中遇到问题,未按预期的效果派发动作.

I am having an issue with the ngrx store not dispatching an action to the effect supposed to deal with it.

这是尝试分发的组件:

  signin() {
    this.formStatus.submitted = true;
    if (this.formStatus.form.valid) {
      this.store.dispatch(new StandardSigninAction(this.formStatus.form.value.credentials));
    }
  }

动作:

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;

效果:

  @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);
        })
    );

我可以在调试中看到该组件确实调用了dispatch方法.我还可以确认StandardSigninAction确实是实例化的,因为构造器中的断点被击中.

I can see in debug that the component does call the dispatch method. I can also confirm that StandardSigninAction is indeed instantiated because the breakpoint in the constructor is hit.

但是standardSignin$效果没有被调用...

But the standardSignin$ effect is not called...

什么可能导致无法调用效果?

What can possibly cause an effect not being called?

如何调试商店中发生的事情?

How can I debug what is going on within the store?

有人可以帮忙吗?

P.S.我确实在导入中运行了以下效果:

P.S. I do run the above effect as follows in my imports:

EffectsModule.run(SessionEffects),

编辑:这是我的SessionSigninService.signin方法(返回一个Observable)

edit: Here is my SessionSigninService.signin method (does return an 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'));
  }

推荐答案

这不会是一个确定的答案,但希望会有所帮助.

This is not going to be a definitive answer, but, hopefully, it will be helpful.

开始之前:

  • 确保您使用的是最新版本的@ngrx软件包(适用于您所使用的Angular版本).
  • 如果您更新了任何软件包,请确保重新启动开发环境(即,重新启动捆绑程序,服务器等)
  • Make sure you are using the latest versions of the @ngrx packages (that are appropriate for the version of Angular you are using).
  • If you've updated any packages, make sure you re-start your development environment (that is, restart the bundler, the server, etc.)

如果您尚未这样做,则应查看

If you've not done so already, you should have a look at the implementation of the Store - so that you make some educated guesses as to what could be going wrong. Note is that the Store is pretty light. It's both an observable (using the state as its source) and an observer (that defers to the dispatcher).

如果您查看 store.dispatch ,您会看到它是的别名 store.next ,其调用< Dispatcher 上的c12>

If you look at store.dispatch you'll see that it's an alias for store.next, which calls next on the Dispatcher.

所以打电话:

this.store.dispatch(new StandardSigninAction(this.formStatus.form.value.credentials));

应该只看到调度程序发出的动作.

should just see an action emitted from the dispatcher.

Actions 可以观察到的效果注入的效果也很轻.只是使用Dispatcher作为其来源的可观察对象.

The Actions observable that's injected into your effects is also pretty light. It's just an observable that uses the Dispatcher as its source.

要查看通过效果流过的动作,可以替换为:

To look at the actions that are flowing through the effect, you could replace this:

@Effect()
standardSignin$: Observable<Action> = this.actions$
  .ofType(session.ActionTypes.STANDARD_SIGNIN)

与此:

@Effect()
standardSignin$: Observable<Action> = this.actions$
  .do((action) => console.log(`Received ${action.type}`))
  .filter((action) => action.type === session.ActionTypes.STANDARD_SIGNIN)

ofType不是运算符;这是一种方法,因此要添加基于do的日志记录,需要将其替换为filter.

ofType is not an operator; it's a method, so to add do-based logging, it needs to be replaced with a filter.

正确记录日志后,如果您接收到动作,则该效果的实现存在问题(或者动作类型的字符串/常量不是您想的那样,并且有些不匹配).

With the logging in place, if you are receiving the action, there is something wrong with the effect's implementation (or maybe the action types' strings/constants aren't what you think they are and something is mismatched).

如果效果未接收到已分派的动作,则最可能的解释是,您通过其分配StandardSigninActionstore与您的效果所使用的store不同-即,您有DI的问题.

If the effect is not receiving the dispatched action, the most likely explanation would be that the store through which you are dispatching the StandardSigninAction is not that same store that your effect is using - that is, you have a DI problem.

如果是这种情况,您应该查看与您说的其他SessionEffects有所不同的地方. (至少您有工作的地方,这是开始实验的好地方.)它们是从其他模块中派发的吗?分派StandardSigninAction的模块是功能模块吗?

If that is the case, you should look at what differs from the other SessionEffects that you say are working. (At least you have something working, which is a good place to start experimenting.) Are they dispatched from a different module? Is the module that dispatches StandardSigninAction a feature module?

如果您破解了一个正常工作的SessionEffects之一,用StandardSigninAction替换了其已调度的动作,会发生什么?这样效果就开始了吗?

What happens if you hack one of the working SessionEffects to replace its dispatched action with StandardSigninAction? Does the effect then run?

请注意,此答案末尾的问题不是我要回答的问题;这些是您应该问自己并进行调查的问题.

这篇关于从组件分派动作时未调用ngrx效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆