2017-12-27 210 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