Застрял в бесконечном цикле, когда не отправляет действие в ngrx/effects

я использую Angular2 и ngrx/store и ngrx / effects для управления состоянием.

когда определенное действие не удается, я хочу показать сообщение об ошибке, но похоже, что я не могу выполнить это задание @Effects() блок. См. следующее:

  @Effect() selectOfficeFail$ = this.actions$
   .ofType(SelectOfficeActions.LOAD_FAIL)
   .do(() => {
     alert('Error! No offices found!'); // I keep entering here
  });

при запуске кода выше предупреждение запускается бесконечное количество раз, пока браузер не аварийно завершит работу. Кажется @Effect() до вернуть dispatch() но я не понимаю, почему. И почему alert () выше запустить бесконечное количество раз?

Edit: Я не диспетчеризация SelectOfficeActions.LOAD_FAIL несколько раз. Только один раз

3 ответов


проблема в том, что do позволяет действию протекать через ваш эффект, а затем действие снова отправляется магазином. Вы могли бы использовать filter чтобы предотвратить это:

@Effect() selectOfficeFail$ = this.actions$
  .ofType(SelectOfficeActions.LOAD_FAIL)
  .do(() => {
    alert('Error! No offices found!'); // I keep entering here
  })
  .filter(() => false); 

[обновление] Теперь лучший способ сделать это-использовать такой:

@Effect({dispatch: false}) selectOfficeFail$ = this.actions$
    .ofType(SelectOfficeActions.LOAD_FAIL)
    .do(() => {
        alert('Error! No offices found!'); // I keep entering here
    });

это означает "реагирует на это действие, но не отправляет другое".


Да ты прав @effect необходимо отправить новое действие, но я думаю, что в вашей логике приложения что-то не так.

вы не должны отправлять SelectOfficeActions.LOAD_FAIL действие в компоненте или службе, а скорее действие загрузки, которое вызывает @Effect а эффект, в свою очередь, передает LOAD_COMPLETE или LOAD_FAIL на основе критериев.

что-то вроде этого пример из библиотеки github

 @Effect() login$ = this.updates$
      // Listen for the 'LOGIN' action
      .whenAction('LOGIN')
      // Map the payload into JSON to use as the request body
      .map(update => JSON.stringify(update.action.payload))
      .switchMap(payload => this.http.post('/auth', payload)
        // If successful, dispatch success action with result
        .map(res => ({ type: 'LOGIN_SUCCESS', payload: res.json() }))
        // If request fails, dispatch failed action
        .catch(() => Observable.of({ type: 'LOGIN_FAILED' }));
      );