标签: ngrx-effects

在lettable rxjs运算符的组合管道中捕获错误

我们刚刚将其中一个应用程序升级到Angular 5,并开始转换为rxjs v5.5中引入的lettable 运算符.

因此,我们使用.pipe()运算符将可观察的管道重写为新语法.

我们之前的代码看起来像这样,如果抛出错误,则.catch()内部.switchMap()不会中断效果的运行.

@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.map((action: LoadData) => action.payload)
.withLatestFrom(this.store.select(getCultureCode))
.switchMap(([payload, cultureCode]) => this.dataService.loadData(payload, cultureCode)
  .map(result => {
    if (!result) {
      return new LoadDataFailed('Could not fetch data!');
    } else {
      return new LoadDataSuccessful(result);
    }
  })
  .catch((err, caught) => {
    return Observable.empty();
  });
  );
Run Code Online (Sandbox Code Playgroud)

如果在调用中抛出错误dataService,它将被捕获并处理(简化了错误处理).

有了新的语法和用法.pipe(),我们现在有了这个

@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.pipe(
  map((action: LoadData) => action.payload),
  withLatestFrom(this.store.select(getCultureCode)),
  switchMap(([payload, cultureCode]) => this.dataService.loadData(payload, cultureCode)),
  map(result => …
Run Code Online (Sandbox Code Playgroud)

rxjs ngrx-effects angular ngrx-store angular5

26
推荐指数
1
解决办法
4万
查看次数

NgRx:在单个效果中调度多个操作

我需要在调用 API 请求后分派多个操作。我目前正在使用此代码在 API 请求完成后分派一个操作:

 changeStatus$ = createEffect(() => 
  this.actions$.pipe(
    ofType(fromJtDetail.changeStatus),
    switchMap(action =>
      this.jtDetailService.changeStatus(action.entity,action.jobTicketId).pipe(
        map(res => fromJtDetail.statusChanged({changedStatus: action.entity.newStatus})),
        catchError(error => EMPTY)
))));
Run Code Online (Sandbox Code Playgroud)

在这个效果中调度更多的动作很重要,不能为此编写另一个效果。

rxjs ngrx ngrx-effects angular

19
推荐指数
2
解决办法
3万
查看次数

从组件调度操作时不调用ngrx效果

我遇到了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$ …
Run Code Online (Sandbox Code Playgroud)

ngrx ngrx-effects

16
推荐指数
4
解决办法
1万
查看次数

Angular ngrx - 显示正在加载gif

我有这样的副作用:

@Effect()
FetchAllOrders$ = this.actions$
    .ofType(SalesOrderActions.FETCH_ALL_ORDERS)
    .switchMap((action: Action) => {
        return this.soApiService.getUsersSalesOrders(action.payload);
    })
    .map((salesOrders: ListDto<SalesOrderList>) => this.actions.fetchAllOrdersSuccess(salesOrders));
Run Code Online (Sandbox Code Playgroud)

我想在效果开始时显示加载符号并在结尾隐藏它.

我创建了一组独立的Actions,Reducers和store状态来处理显示加载符号.

export class BusyActions {
static SHOW_SPINNER = "SHOW_SPINNER";
static HIDE_SPINNER = "HIDE_SPINNER";

showSpinner(): Action {
   return { type: BusyActions.SHOW_SPINNER };
}

hideSpinner(): Action {
   return { type: BusyActions.HIDE_SPINNER };
}

export const BusyState: IBusyState = {
   visible: false,
   busy: false
};
Run Code Online (Sandbox Code Playgroud)

我这样做是因为加载状态需要与其他模块,状态等共享.

如何从副作用中调用我的BusyActions?我需要在开始时调用SHOW_SPINNER,最后调用HIDE_SPINNER.

我做得对吗?或者有更好的方法来处理这个问题吗?

ngrx ngrx-effects angular ngrx-store

16
推荐指数
2
解决办法
1964
查看次数

ngRx状态更新和效果执行顺序

我对这个问题有自己的看法,但最好仔细检查并确定.感谢您的关注并尝试提供帮助.这里是:

想象一下,我们正在调度一个触发一些状态变化的动作,并且还附加了一些效果.所以我们的代码必须做两件事 - 改变状态并做一些副作用.但这些任务的顺序是什么?我们是在同步吗?我相信,首先,我们改变状态,然后做副作用,但有可能,这两个任务之间可能会发生其他事情吗?像这样:我们改变状态,然后在我们之前做过的HTTP请求上得到一些响应并处理它,然后做副作用.

[编辑:]我决定在这里添加一些代码.而且我也简化了它.

州:

export interface ApplicationState {
    loadingItemId: string;
    items: {[itemId: string]: ItemModel}
}
Run Code Online (Sandbox Code Playgroud)

操作:

export class FetchItemAction implements  Action {
  readonly type = 'FETCH_ITEM';
  constructor(public payload: string) {}
}

export class FetchItemSuccessAction implements  Action {
  readonly type = 'FETCH_ITEM_SUCCESS';
  constructor(public payload: ItemModel) {}
}
Run Code Online (Sandbox Code Playgroud)

减速器:

export function reducer(state: ApplicationState, action: any) {
    const newState = _.cloneDeep(state);
    switch(action.type) {
        case 'FETCH_ITEM':
            newState.loadingItemId = action.payload;
            return newState;
        case 'FETCH_ITEM_SUCCESS':
            newState.items[newState.loadingItemId] = action.payload;
            newState.loadingItemId = null;
            return newState;
        default: …
Run Code Online (Sandbox Code Playgroud)

javascript ngrx ngrx-effects angular ngrx-store

15
推荐指数
1
解决办法
6184
查看次数

为什么必须ngrx/redux效果返回动作?是否正在使用像榆树这样的不良行为?

我正在使用带有Angular和ngrx/store和ngrx/effects的redux风格的状态管理设计.每当我不从效果中返回动作时,我都会收到错误:

Cannot read property 'type' of undefined
Run Code Online (Sandbox Code Playgroud)

我研究了这个问题,发现在榆树架构中有一种称为"noop"的动作,当你不想用你的效果链接另一个动作时,你可以调用任何东西.在任何地方召唤这种noop行动对我来说都是非常重复的.我想知道这是否是一个不好的做法.有没有理由你不能产生不返回动作的效果?效果的意图总是有1个动作引发另一个动作吗?我想知道我是否误解了如何使用效果.

谢谢!

redux ngrx ngrx-effects angular ngrx-store

12
推荐指数
1
解决办法
5680
查看次数

如何在@ngrx/effects中等待2个动作

可以影响像Promise.all这样的两个动作吗?例:

@Effect()
pulic addUser() {
   return this.actions$.ofType(user.ADD)
      .switchMap(() => {
         return this.userService.add();
      })
      .map(() => {
         return new user.AddSuccessAction();
      });
}

@Effect()
pulic addUserOptions() {
   return this.actions$.ofType(userOptions.ADD)
      .switchMap(() => {
         return this.userOptionsService.add();
      })
      .map(() => {
         return new userOptions.AddSuccessAction();
      });
}

@Effect()
public complete() {
   return this.actions$.ofType(user.ADD_SUCCESS, userOptions.ADD_SUCCESS)
      // how to make it works like Promise.all ?
      .switchMap(() => {
         return this.statisticService.add();
      })
      .map(() => {
         return new account.CompleteAction();
      });
}
Run Code Online (Sandbox Code Playgroud)

更新 我想要实现的是Promise.all的simillar行为.如何并行调度两个效果,等待所有效果都解决,然后发出第三个动作.像https://redux-saga.js.org/docs/advanced/RunningTasksInParallel.html这样的承诺它是非常明显的:

Promise.all([fetch1, fetch2]).then(fetch3);
Run Code Online (Sandbox Code Playgroud)

是否有可能在ngrx /效果?或者在ngrx /效果中它是错误的方式? …

typescript ngrx ngrx-effects angular ngrx-store

12
推荐指数
3
解决办法
9757
查看次数

角度:ngrx 效果未触发

我已经开发了一些实现 Redux (NgRx) 的 Angular 应用程序。我无法弄清楚我当前项目的问题。

行动:

export class GetUserFromStorage implements Action {
  readonly type = UserActionTypes.GetUserFromStorage;
}

export class GetUserFromStorageSuccess implements Action {
  readonly type = UserActionTypes.GetUserFromStorageSuccess;
  constructor(public payload: User | null) { }
}

export class GetUserFromStorageFail implements Action {
  readonly type = UserActionTypes.GetUserFromStorageFail;
  constructor(public payload: string) { }
}
Run Code Online (Sandbox Code Playgroud)

减速器:

case UserActionTypes.GetUserFromStorageSuccess:
    return {
        ...state,
        user: action.payload,
        error: ''
    };

case UserActionTypes.GetUserFromStorageFail:
    return {
        ...state,
        error: action.payload
    };
Run Code Online (Sandbox Code Playgroud)

效果:

@Effect() getUserFromStorage$:
Observable<userActions.GetUserFromStorageSuccess | userActions.GetUserFromStorageFail>
    = this.actions$.pipe(
        ofType(userActions.UserActionTypes.GetUserFromStorage), …
Run Code Online (Sandbox Code Playgroud)

ngrx ngrx-effects angular

12
推荐指数
1
解决办法
4135
查看次数

ngrx链接动作/效果 - 例如登录然后导航

我是ngrx和Redux风格架构的新手,我在理解如何链接动作/效果方面遇到了问题.一个例子是实现基本功能,例如在用户登录后采取行动.我的核心斗争是在用户登录后要采取的行动将根据应用程序的当前状态而变化 - 用户可能在任何地方在提交登录提示/页面时在应用程序中.

我见过的任何一些例子,一旦用户登录就会发生硬编码效果.在我的场景中,这不符合上述说法,我并不总是希望同样的动作发生.

以下是包含登录组件的主页的一些示例代码.在这种情况下,我希望用户在登录后重定向到"/ buy".

@Component(..)
export class HomePageComponent {
    constructor(private store: Store<any>) {
    }

    public onLoginSubmitted(username, password) {
        this.store.dispatch(new loginActions.Login({username, password}));
        // once this has happened successfully navigate to /buy    
    }

}
Run Code Online (Sandbox Code Playgroud)

示例效果

@Injectable()
export class LoginEffects {

    ......     

    @Effect()
    login$ = this.actions$
        .ofType(loginActions.ActionTypes.LOGIN)
        .switchMap((data) => {
            return this.loginService.login(data.payload)
                .map(() => new loginActions.LoginSuccess({loggedIn: true, isLoggingIn: false}))
                .catch((error) => {
                    return of(new loginActions.LoginError({loggedIn: false, isLoggingIn: false}));
                });
        });
    ......
}
Run Code Online (Sandbox Code Playgroud)

关于如何解决这个问题,我有几点想法 - 但他们都不是正确的.这些包括

  • 使用登录有效负载传递数据以确定下一步要采取的操作
  • 写一些在LoginSuccess上采取行动但在某个更高级别过滤的效果
  • 通过监听商店中的事件来编写特定于组件的效果(这是可能/不好的做法吗?)
  • 从商店读取有关当前登录状态的数据并在组件中对此进行操作.然而,这种逻辑会立即运行,这可能不会产生预期的效果

任何人都可以指出我应该如何解决这个问题的正确途径/现有例子吗?

ngrx ngrx-effects angular

11
推荐指数
1
解决办法
6130
查看次数

我应该在哪里放置旨在转换ngrx商店的数据的业务逻辑:效果还是减少?

我的问题涉及ngrx 效应减速器.

在将它放入ngrx存储之前,我需要转换从后端检索的数据.从后端检索的数据是一个普通数组Message(Message在我的应用程序中是一个自定义类型):

Message[]
Run Code Online (Sandbox Code Playgroud)

我需要将数组转换为以下内容:

Map<string, Message[]>
Run Code Online (Sandbox Code Playgroud)

基本上我是按对方(收件人或发件人)ID(密钥)对用户的邮件进行分组.

我不知道从哪里执行转换Message[]Map<string, Message[]>:我应该把转型业务逻辑到@Effect或进入减速功能

redux ngrx ngrx-effects

10
推荐指数
2
解决办法
2051
查看次数