使用 NgRX 实体标准化 Api 响应

Posted

技术标签:

【中文标题】使用 NgRX 实体标准化 Api 响应【英文标题】:Normalise Api response with NgRX Entity 【发布时间】:2020-01-09 07:09:58 【问题描述】:

是否可以采用嵌套的 JSON api 响应并使用 NgRx 实体库对其进行规范化? 如果我有一个看起来像这样的对象:

[
    
        "id": "1",
        "title": "My first post!",
        "author": 
            "id": "123",
            "name": "Paul"
        ,
        "comments": [
            
                "id": "249",
                "content": "Nice post!",
                "commenter": 
                    "id": "245",
                    "name": "Jane"
                
            ,
            
                "id": "250",
                "content": "Thanks!",
                "commenter": 
                    "id": "123",
                    "name": "Paul"
                
            
        ]
    ,
    
        "id": "2",
        "title": "This other post",
        "author": 
            "id": "123",
            "name": "Paul"
        ,
        "comments": [
            
                "id": "251",
                "content": "Your other post was nicer",
                "commenter": 
                    "id": "245",
                    "name": "Jane"
                
            ,
            
                "id": "252",
                "content": "I am a spammer!",
                "commenter": 
                    "id": "246",
                    "name": "Spambot5000"
                
            
        ]
    
]

我想用 NgRx Entity 让它尽可能平坦,这可能吗?如果可以,怎么做?

我尝试过使用 normalizr 库,它可以很好地展平对象,但它不适合 NgRx 辅助函数,例如 createReducers() 和 createActions()。

有人知道吗?

【问题讨论】:

【参考方案1】:

不,@ngrx/entity 不提供规范化实用程序。 它包含用于存储和读取集合到存储的 CRUD 操作。

【讨论】:

所以为了实现我想要的,我应该使用 normalizr 库并规范化 api 响应,然后将输出存储到单独的实体中? 是的,您必须手动完成或使用 normilizr 之类的库 太棒了!谢谢您的帮助!将此标记为答案!【参考方案2】:

当然

您可能会在任何地方产生类似于官方文档 (https://ngrx.io/guide/effects) 中的效果:

loadMovies$ = createEffect(() => this.actions$.pipe(
    ofType('[Movies Page] Load Movies'),
    mergeMap(() => this.moviesService.getAll()
      .pipe(
        // map -> flat your response here
        map(movies => ( type: '[Movies API] Movies Loaded Success', payload: movies )),
        catchError(() => EMPTY)
      ))
    )
  );

您可以简单地预先放置另一张地图来展平电影数组。您可以使用 lodash 函数来执行此操作。

【讨论】:

无需使用lodash 这不会为扁平对象创建单独的实体...

以上是关于使用 NgRX 实体标准化 Api 响应的主要内容,如果未能解决你的问题,请参考以下文章

如何在标准化状态下使用结果数组以排序顺序呈现帖子

text 标准的json api响应格式

在 redux 应用程序中,在哪里为实体生成唯一 ID?

IIS 托管实体框架 CORS 的 Angular 客户端不允许响应

用“Normalizr”可视化 API 响应的更好方法

NGRX - 使用哈希而不是数组来表示状态