ngxs-labs / entity-state

⏱ WIP: Entity adapter
48 stars 12 forks source link

Arrays or maps of SubStates #12

Closed splincode closed 5 years ago

splincode commented 6 years ago

I think this should be controlled at the entity state level.

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[x ] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[ ] Other... Please describe:

Current behavior

Currently you can't create a SubState within an array or map.

Expected behavior

I would like to be able to use a Map of RowStates in a StateModel:

import {State} from '@ngxs/store';

export interface RowStateModel {
  id: number; // Or string
}

export interface GridStateModel {
  id: number; // Or string
  rows: Map<number, RowState>;
}

/**
 * GridCollectionStateModel has a map of GridStates,
 * where the key refers to the dataname of the GridStateModel.
 */
export interface GridCollectionStateModel {
  grids: Map<number, GridState>;
}

@State<RowStateModel>({
  name: 'row',
  defaults: {
    id: -1
  }
})
export class RowState {}

@State<GridStateModel>({
  name: 'grid',
  defaults: {
    id: -1,
    rows: new Map<number, RowState>()
  }
})
export class GridState {}

@State<GridCollectionStateModel>({
  name: 'grid-collection',
  defaults: {
    grids: new Map<number, GridState>()
  }
})
export class GridCollectionState {}

This should create a state that looks like this:

{
  "grids": {
    "GridState_0": {
      "id": 0,
      "rows": {
        "RowState_0": {
          "id": 0
        },
        "RowState_1": {
          "id": 1
        }
      }
    },
    "GridState_1": {
      "id": 1,
      "rows": {
        "RowState_0": {
          "id": 0
        }
      }
    }
  }
}

What is the motivation / use case for changing the behavior?

In my application I have a use case where I have a complex data tree which would need to have a SubState. I have a collection of grids that can be displayed at the same time. Each grid has a dataname (unique identifier), which it uses to fetch the corresponding data. On top of that, each grid has a set of hierarchical rows, for which I also could use the SubStates.

JanMalch commented 6 years ago

Just so I understand: dynamically nested entity states? For example:

// top level entity state
{  
   entities:{  
      ngxs:{  
         entities:{  
            "Todo 1":{  
               title:"Todo 1",
               descr:"..."
            },
            "Todo 2":{  
               title:"Todo 2",
               descr:"...2"
            },
         },
         loading:false,
         active:undefined,
         error:undefined
      },
      angular:{  
         entities:{  
            "Todo 1":{  
               title:"Todo 1",
               descr:"..."
            }
         },
         loading:false,
         active:"Todo 1",
         error:undefined
      }
   },
   loading:false,
   active:"ngxs",
   error:undefined
}

or should there be an entity state class that mimics this by normalizing data? So the user thinks the structure is hierarchical like this, but internally it's normalized?

markwhitfeld commented 5 years ago

I don't think that this really applies to this plugin. As mentioned in this https://github.com/ngxs/store/issues/666#issuecomment-441402693 the recommended approach is to normalise your state. @JanMalch feel free to close this issue.