ngrx dealing with nested array in object

前端 未结 1 1053
日久生厌
日久生厌 2021-02-01 06:11

I am learning the redux pattern and using ngrx with angular 2. I am creating a sample blog site which has following shape.

相关标签:
1条回答
  • 2021-02-01 06:52

    Instead of having a nested structure

    export interface BlogContent {
      id: string;
      header: string;
      tags: string[];
      title: string;
      actualContent: ActualContent[]; <------ NESTED
    }
    

    You should have a normalized state.

    For example here you should have something like :

    // this should be into your store
    export interface BlogContents {
      byId: { [key: string]: BlogContent };
      allIds: string[];
    }
    
    // this is made to type the objects you'll find in the byId
    export interface BlogContent {
      id: string;
      // ...
      actualContentIds: string[];
    }
    
    // ----------------------------------------------------------
    
    // this should be into your store
    export interface ActualContents {
      byId: { [key: string]: ActualContent };
      allIds: string[];
    }
    
    export interface ActualContent {
      id: string;
      // ...
    }
    

    So if you try to populate your store it'd look like that :

    const blogContentsState: BlogContents = {
      byId: {
        blogContentId0: {
          id: 'idBlogContent0',
          // ...
          actualContentIds: ['actualContentId0', 'actualContentId1', 'actualContentId2']
        }
      },
      allIds: ['blogContentId0']
    };
    
    const actualContentState: ActualContents = {
      byId: {
        actualContentId0: {
          id: 'actualContentId0',
          // ...
        },
        actualContentId1: {
          id: 'actualContentId1',
          // ...
        },
        actualContentId2: {
          id: 'actualContentId2',
          // ...
        }
      },
      allIds: ['actualContentId0', 'actualContentId1', 'actualContentId2']
    };
    

    In your logic or view (for example with Angular), you need your nested structure so you can iterate over your array and thus, you don't want to iterate on a string array of IDs. Instead you'd like actualContent: ActualContent[];.

    For that, you create a selector. Every time your store change, your selector will kicks in and generate a new "view" of your raw data.

    // assuming that you can blogContentsState and actualContentsState from your store
    const getBlogContents = (blogContentsState, actualContentsState) =>
      blogContentsState
        .allIds
        .map(blogContentId => ({
          ...blogContentsState.byId[blogContentId],
    
          actualContent: blogContentsState
            .byId[blogContentId]
            .actualContentIds
            .map(actualContentId => actualContentsState.byId[actualContentId])
        }));
    

    I know it can be a lot to process at the beginning and I invite you to read the official doc about selectors and normalized state

    As you're learning ngrx, you might want to take a look into a small project I've made called Pizza-Sync. Code source is on Github. It's a project were I've done something like that to demo :). (You should also definitely install the ReduxDevTools app to see how is the store).

    I made a small video focus only on Redux with Pizza-Sync if you're interested : https://youtu.be/I28m9lwp15Y

    0 讨论(0)
提交回复
热议问题