2017-12-27 211 views
4

我尝试查找此方案的最佳做法,但找不到。ngrx/reducex操作环境的最佳做法

问题: 我不想再重复动作的文件,就像在我的例子 家todos.actions和运动待办事项-行动,我想用同样的对dos.action文件。和相同的减速器。

例如: 我写例如待办事项应用程序,在这个例子中,你可以看到这个问题,如果我派遣一个行动型“ADD_TODO_ASYNC”,它会在家里(效果和减速机)派遣,和运动(效果减速机)

todos.actions.ts

const ADD_TODO_ASYNC = 'ADD TODO ASYNC'; 
const ADD_TODO_COMPLETE = 'ADD TODO COMPLETE'; 
const ADD_TODO_FAILD = 'AD TODO FAILD'; 

class addTodoComplete { 
    type = ADD_TODO_COMPLETE; 
} 
class addTodoFaild { 
    type = ADD_TODO_COMPLETE; 
} 

export type Actions = addTodoComplete | addTodoFaild; 

sport.effects.ts

@Injectable() 
export class SportTodosService { 

    @Effect() ADD_TODO_ASYNC$ = this.actions$.ofType(TodosActionTypes.ADD_TODO_ASYNC) 
    .map(toPayload) 
    .swithMap((todo: Todo) => this.api.addTodo(todo)) 
    .map((todo: Todo) => TodosActionTypes.addTodoComplete(todo)) 
    constructor(
     private actions$: Actions, 
     private api: api 
    ) { } 

} 

个home.effects.ts

export class HomeTodosService { 
    @Effect() ADD_TODO_ASYNC$ = this.actions$.ofType(TodosActionTypes.ADD_TODO_ASYNC) 
     ... 
    constructor(
     ... 
    ) { } 

} 

减速

function todosReducer(state, action: TodosActionTypes.Actions) { 
    switch (action.type) { 
     case TodosActionTypes.ADD_TODO_COMPLETE: 
      return state; 
     default: 
      return state; 
    } 
} 

app.module.ts

@NgModule({ 
    declarations: [ 
     AppComponent 
    ], 
    imports: [ 
     StoreModule.forRoot({ 
     sport: todosReducer, 
     home: todosReducer, 
     }), 
     EffectsModule.forRoot([ 
     SportTodosService 
     HomeTodosService, 
     ]) 
    ], 
    providers: [ 
     api 
    ], 
    bootstrap: [AppComponent] 
    }) 
    export class AppModule { } 

我试着去了解什么是此方案的最佳实践? 用“HOME_ADD_TODO”&'SPORT_ADD_TODO'等上下文编写动作?

还是有官方的方式?

,如果你知道解决办法,如果该解决方案是终极版,不关心或NGRX

感谢所有

回答

1

要理解这个问题,您需要再次考虑您的应用程序体系结构。 一般可重复使用的减速器/动作不正确。

为什么这是不正确的?在目前看来,编写可重复使用的缩减器和动作,更少的样板,而不是“干”似乎很棒。在你的应用程序的例子。家和运动的'ADD_TO_DO'是平等的。

但在未来它将是危险的,认为你的老板/ costumers需要在体育add_to_do未来。如果您更改可重复使用的减速器中的逻辑。你的应用会崩溃。 (你可以用if语句来修补可重复使用的reducer,以使它可以正常工作,但是如果你的应用程序增长了,它将不会灵活/可读/维护)。

所以是的,你似乎需要在这种情况下写2个减速器和2个动作文件。在目前它充满平等,但在未来它将是优势和灵活性。

祝你好运!

0

在这些情况下的解决方法是用行动命名空间

行动常量充当行动的唯一标识符。由于应用程序中可能存在许多与存储的不同切片相对应的操作,因此我们可以通过使用操作命名空间的概念来防止重复操作逻辑故障的存储。检查了这一点:

// todos.actions.ts 
export const ADD_TODO = '[Home] Add Todo'; 

我们只是一个名称空间追加到行动常量,理想情况下,对应于商店的切片,我们使用的名称 - 您目前所在的功能模块的一般名称工作。

如果我们发现自己通过日志记录操作来调试应用程序,这个命名空间将清楚我们正在解决哪些存储切片和什么操作上下文,因为我们会看到类似这样的事情(假设我们将视图从“Home”以“体育”):

[Home] Add Todo 
[Home] Add Todo Success 
[Sport] Add Todo 
[Sport] Add Todo Success 

检查SOURCE更多的细节

+0

我知道名称间距,但我填写,如果我有我的应用程序中的10个主题待办事项我会复制过去相同的操作? 和你的解决方案,我将如何处理它在一个reducer? – Alin

+0

我想你不明白我的问题!因为在你的方式,我需要写减速器和行动两次 – Alin

1

Here是一些模式和做法NGRX的链接。

它旨在按照您描述的方式工作。 this.actions$是一个Observable,所以无论你使用它,它都会发射出去。由于TodosActionTypes.ADD_TODO_ASYNChome.effects.tssport.effects.ts中都是相同类型,所以它会在两个地方发射。

我不确定您可以避免在您的案例中单独采取行动,但可以减少样板代码的数量。

我会尝试这样的事:

todos.actions.ts

abstract class addTodoComplete{ 
    constructor(readonly type: string){ 
     //rest of the behavior 
    } 
} 
abstract class addTodoFailed{ 
    constructor(readonly type: string){ 
    //rest of the behavior 
    } 
} 

todos.sport-actions.ts

const ADD_TODO = "[Sport] Add Todo"; 
const ADD_TODO_FAILED = "[Sport] Add Todo Failed"; 
class sportsAddTodoComplete extends addTodoComplete{ 
    constructor(){ 
     super(ADD_TODO); 
     //rest of the behavior 
    } 
} 
class sportsAddTodoFailed extends addTodoFailed{ 
    constructor(){ 
    super(ADD_TODO_FAILED); 
     //rest of the behavior 
    } 
} 

也是一样的家庭版。

此外,你可能会有单独的SportTodosActionTypesHomeTodosActionTypes

你不会完全从“复制粘贴”中拯救你自己,但它应该在一定程度上有所帮助。

编辑:

至于减速,这是事实,使用这种方法,你将不得不写两个减速,但它并没有成为一个“复制 - 粘贴”的工作

sport.reducer.ts

import { todoReducer } from './reducer'; 

export function sportsTodoReducer(state, action: SportTodoActionTypes.Actions){ 
    todoReducer(state, action); 
} 

类似的还适用于home版本。

+0

我知道他们会发出两个!我举个例子来解释这个问题! 我不喜欢你的方式,因为在这种情况下,我需要为运动动作和家庭行为编写待办事项减速器 – Alin

+0

我知道他们会同时发出!我举个例子来解释这个问题! 行动不是问题,如果我们为上下文编写独特的行动,在您的解决方案中,我需要2个reducer – Alin

+0

我已编辑我的帖子。如果你想单独处理,你将不得不为体育和家庭采取不同的行动。这意味着不同的行动,减少,影响。您只能减少复制粘贴代码的数量。 – eminlala