使用 ngrx 商店时如何在 Angular 2 中导航
Howto navigate in Angular 2 when using ngrx store
我正在使用 ngrx store (4.x) 和 Angular 4. 我使用 effects 在后端进行 CRUD 操作,如下例在后端添加任务 API.
效果:
@Effect()
addTask: Observable<Action> = this.actions$
.ofType(LeadAction.ADD_TASK)
.map((action: LeadAction.AddTaskAction) => action.payload)
.switchMap((task: TaskViewModel) => {
return this.leadApi.leadAddTask(task.LeadId, task)
.map((taskResult: TaskViewModel) => {
return new LeadAction.AddTaskSuccessAction(taskResult);
})
.catch((e: any) => of(new LeadAction.AddTaskFailureAction(e)));
});
任务编辑组件:
onSave(): void {
this.store.dispatch(new AddTaskAction(this.task));
// **** NAVIGATE TO PAGE TaskListComponent or OverviewComponent ON SUCCESS
// OR
// **** NAVGIATE TO PAGE Y ON ERROR
}
问题:在我的组件中,我需要导航到不同的页面,但我现在很难将此逻辑放在哪里?
特别是当我考虑以下场景时,TaskEditComponent 由不同的组件'called':
应导航回 TaskListComponent:
OverviewComponent->TaskListComponent->TaskEditComponent返回List
应导航回 OverviewComponent:
OverviewComponent->TaskEditComponent
使用 ngrx
,让您的商店也处理路由器状态是有意义的,保留 redux 范例。然后您只需在效果中发送一个路由器操作以响应您的成功操作。
这具有能够“time travel”路由以及应用状态的其余部分的额外好处。
幸运的是,已经有一个implementation of router-store integration可以使用了。
你可以做这样的事情(只是一个指导,增强你的需求):
app.module
import { StoreRouterConnectingModule, routerReducer } from '@ngrx/router-store';
import { App } from './app.component';
@NgModule({
imports: [
BrowserModule,
StoreModule.forRoot({ routerReducer: routerReducer }),
RouterModule.forRoot([
// ...
{ path: 'task-list', component: TaskListComponent },
{ path: 'error-page', component: ErrorPageComponent }
]),
StoreRouterConnectingModule
],
bootstrap: [App]
})
export class AppModule { }
task.effects
import { go } from '@ngrx/router-store';
@Effect()
addTask: Observable<Action> = this.actions$
.ofType(LeadAction.ADD_TASK_SUCCESS)
.map((action: LeadAction.AddTaskSuccessAction) => action.payload)
.map((payload: any) => go('/task-list')); // use payload to construct route options
@Effect()
addTask: Observable<Action> = this.actions$
.ofType(LeadAction.ADD_TASK_FAILURE)
.mapTo(go('/error-page'));
使用具有最新功能的 NGRX v8+ 进行更新:
AppModule:
import { StoreRouterConnectingModule, routerReducer } from '@ngrx/router-store';
import { AppComponent } from './app.component';
@NgModule({
imports: [
BrowserModule,
StoreModule.forRoot({ routerReducer }),
RouterModule.forRoot([
// ...
{ path: 'task-list', component: TaskListComponent },
{ path: 'error-page', component: ErrorPageComponent }
]),
StoreRouterConnectingModule.forRoot(),
],
bootstrap: [AppComponent],
})
export class AppModule {}
任务效果:
@Injectable()
export class TaskEffects {
readonly addTaskSuccess$ = createEffect(() =>
this.actions$.pipe(
ofType(LeadAction.ADD_TASK_SUCCESS),
tap(() => this.router.navigate(['task-list'])),
),
{ dispatch: false },
);
readonly addTaskFailure$ = createEffect(() =>
this.actions$.pipe(
ofType(LeadAction.ADD_TASK_FAILURE),
tap(() => this.router.navigate(['error-page'])),
),
{ dispatch: false },
);
constructor(
private readonly actions$: Actions,
private readonly router: Router,
) {}
}
我正在使用 ngrx store (4.x) 和 Angular 4. 我使用 effects 在后端进行 CRUD 操作,如下例在后端添加任务 API.
效果:
@Effect()
addTask: Observable<Action> = this.actions$
.ofType(LeadAction.ADD_TASK)
.map((action: LeadAction.AddTaskAction) => action.payload)
.switchMap((task: TaskViewModel) => {
return this.leadApi.leadAddTask(task.LeadId, task)
.map((taskResult: TaskViewModel) => {
return new LeadAction.AddTaskSuccessAction(taskResult);
})
.catch((e: any) => of(new LeadAction.AddTaskFailureAction(e)));
});
任务编辑组件:
onSave(): void {
this.store.dispatch(new AddTaskAction(this.task));
// **** NAVIGATE TO PAGE TaskListComponent or OverviewComponent ON SUCCESS
// OR
// **** NAVGIATE TO PAGE Y ON ERROR
}
问题:在我的组件中,我需要导航到不同的页面,但我现在很难将此逻辑放在哪里?
特别是当我考虑以下场景时,TaskEditComponent 由不同的组件'called':
应导航回 TaskListComponent:
OverviewComponent->TaskListComponent->TaskEditComponent返回List
应导航回 OverviewComponent:
OverviewComponent->TaskEditComponent
使用 ngrx
,让您的商店也处理路由器状态是有意义的,保留 redux 范例。然后您只需在效果中发送一个路由器操作以响应您的成功操作。
这具有能够“time travel”路由以及应用状态的其余部分的额外好处。
幸运的是,已经有一个implementation of router-store integration可以使用了。
你可以做这样的事情(只是一个指导,增强你的需求):
app.module
import { StoreRouterConnectingModule, routerReducer } from '@ngrx/router-store';
import { App } from './app.component';
@NgModule({
imports: [
BrowserModule,
StoreModule.forRoot({ routerReducer: routerReducer }),
RouterModule.forRoot([
// ...
{ path: 'task-list', component: TaskListComponent },
{ path: 'error-page', component: ErrorPageComponent }
]),
StoreRouterConnectingModule
],
bootstrap: [App]
})
export class AppModule { }
task.effects
import { go } from '@ngrx/router-store';
@Effect()
addTask: Observable<Action> = this.actions$
.ofType(LeadAction.ADD_TASK_SUCCESS)
.map((action: LeadAction.AddTaskSuccessAction) => action.payload)
.map((payload: any) => go('/task-list')); // use payload to construct route options
@Effect()
addTask: Observable<Action> = this.actions$
.ofType(LeadAction.ADD_TASK_FAILURE)
.mapTo(go('/error-page'));
使用具有最新功能的 NGRX v8+ 进行更新:
AppModule:
import { StoreRouterConnectingModule, routerReducer } from '@ngrx/router-store';
import { AppComponent } from './app.component';
@NgModule({
imports: [
BrowserModule,
StoreModule.forRoot({ routerReducer }),
RouterModule.forRoot([
// ...
{ path: 'task-list', component: TaskListComponent },
{ path: 'error-page', component: ErrorPageComponent }
]),
StoreRouterConnectingModule.forRoot(),
],
bootstrap: [AppComponent],
})
export class AppModule {}
任务效果:
@Injectable()
export class TaskEffects {
readonly addTaskSuccess$ = createEffect(() =>
this.actions$.pipe(
ofType(LeadAction.ADD_TASK_SUCCESS),
tap(() => this.router.navigate(['task-list'])),
),
{ dispatch: false },
);
readonly addTaskFailure$ = createEffect(() =>
this.actions$.pipe(
ofType(LeadAction.ADD_TASK_FAILURE),
tap(() => this.router.navigate(['error-page'])),
),
{ dispatch: false },
);
constructor(
private readonly actions$: Actions,
private readonly router: Router,
) {}
}