ngrx:调整子状态的属性以支持可重用性

时间:2018-04-05 14:13:31

标签: angular ngrx

问题描述:

我经常重复使用常见的UI元素,例如“Datatable”:

enter image description here

每当向此表添加功能时,我们必须在每个模块中单独添加功能,从而导致大量浪费的工作和代码重复。

解决方案提案:

我想创建这个表的单个有状态实现作为ngModule,这样当我们调整表的核心行为(例如添加一个特性)时,我们只需进行更改在一个地方。

事实证明,实施这一点很困难。我似乎无法解决的主要问题是dataTable的多个实例意味着当一个实例调度一个新操作时,每个实例都会在其各自的reducer中处理它。

为了解决这个问题,我实施了以下脚手架:

Store
→ featureA
    → dataTable
→ featureB
    → dataTable

然后在dataTable组件的ngOnInit()函数中,我使用带有标识符的“forFeature”有效负载调度“InitTable”操作,以指定操作所针对的功能。

然后在featureA& B,我有一个效果,它使用与其标识符匹配的forFeature属性侦听InitTable Action,然后调度“特定于功能”的操作。这看似合适

@Effect()
  tableInit$: Observable<Action> = this.actions$.pipe(
    filter((x: Action) => x['forFeature'] && x['forFeature'] === 'A'), // ‘A’ as id
    ofType(<string>DataTableActionTypes.InitTable),
    map((action: Action) => {
      return new InitATable(); // Action specified at the ‘feature’ level
    })
  );

然后,此功能应由功能级别的reducer捕获,并调整其子dataTable状态的字段。我似乎无法让这部分工作,我想知道它是否违反了试图在父级调整孩子状态的模式?下面是我想象的代码的粗略估计:

export function aReducer(state, action) {
  switch(action.type){
    case AActionTypes.InitATable: {
      return { ...state, dataTable: { ...state.dataTable, feature: ‘A’ } }
    }

    ....

} }

在此之后,在dataTable的reducer内部,在输入典型的switch语句之前,如果dataTable是动作的forFeature属性中的标识符不等于dataTable状态的'feature'字段所包含的标识符,则返回原始状态

export function dataTableReducer(state, action) {
  if(action.forFeature !== state.feature){
    return state;
  }
  switch(action.type){
    case AActionTypes.InitATable: {
      return { ...state, dataTable: { ...state.dataTable, feature: ‘A’ } }
    }

    ....

} }

我相信这应该有用,只要我找到一种方法来单独设置不同dataTables的'feature'值。

更新:与我最初的想法相反,黑客攻击和调试表明问题不在于有不同的dataTable实例,每个实例都听取了针对其他datraTable的操作,但每个不同的引用都是针对子dataTable的事实指向同一个实例。

0 个答案:

没有答案