【问题标题】:@Ngrx/store: how to query models with relationships@Ngrx/store:如何查询具有关系的模型
【发布时间】:2017-11-03 18:04:11
【问题描述】:

我是一个使用 Redux(使用 @ngrx/store)的 Angular 2 应用程序,我以这种方式为商店建模:

{

  modelA: {
    ids: [1, 2],
    entities: { 1: { name: "name modelA 1" },
                2: { name: "name modelA 2" }
              }
  },

  modelB: {
    ids: [5, 8],
    entities: { 5: { name: "name modelB 5" },
                8: { name: "name modelA 8" },
                9: { name: "name modelA 9" }
              }
  } 

}

基本上,我有两种类型的对象:modelA 和 modelB。这暂时没问题。 但是我找不到哪种方法是编写两者之间关系的最佳方式,表示类似modelA的东西有很多modelB(一对多)。我可以这样做吗?

modelAmodelB: {
  entities: {
    1: [5],
    2: [8, 9]
  }
}

这是商店的根目录,它不是来自“modelA”的孩子。 这可能有效,但是我将如何使用@ngrx/store 方法从特定模型A“查询”模型B?因为如果我编写一个读取全局状态并从 modelAmodelB 返回部分状态的选择器函数,则在编写函数时我无法访问其余状态。示例:

compose(getModelAEntities(number[]), getModelAModelBRelations(modelA_id: number), getModelAModelBState() );

我可以使用 Observable.combineLast 进行查询

Observable
.combineLatest(
  this.store.select('contentContents'),
  this.store.select('contents'),
  (relations: any, contents: any) => {
    return relations.entities[1].map( id => {
      return contents.entities[id]
    })
  }
).subscribe( data => {
  console.log(data);
})

但我不知道这是否正确:每当我更改 modelA 实体对象(例如添加一个新对象)时,都会调用 subscribe(),但输出是相同的,因为 modelA 实体都没有更改也不是它的modelB相关对象。

PS:我可以这样查询

export const getModelAModelBs = (id) => {
  return state => 
    state.select( (s: any) => [s.modelAModelB.entities[id], s.modelB.entities])
    .distinctUntilChanged( (prev, next) => {

      const new_m = (next[0] || []).map( id => {
        return next[1][id];
      });

      const old_m = (next[0] || []).map( id => {
        return prev[1][id];
      });

      return prev[0] === next[0] && (JSON.stringify(new_m) === JSON.stringify(old_m))
    })
    .map( ([ids = [], modelBs]) => ids.map( id => modelBs[id]) );
};

//use the selector
this.store.let(getModelAModelBs(1)).subscribe( data => {
  console.log(data)
})

但我不知道这是否是最好的方法。

【问题讨论】:

  • 你可以阅读这篇文章-netbasal.com/…
  • 如果你想要一个实际的例子,你应该看看Pizza-Sync。还有这个file,你可能会特别感兴趣。
  • 尝试在第一次选择时使用 switchMap,然后在第一个数据的基础上,您可以为您的关系查询其他选择,然后返回选择,您将获得值。

标签: javascript angularjs redux ngrx ngrx-store


【解决方案1】:

我在同样的问题上苦苦挣扎,并想出了一个包装器的解决方案。

请查看ngrx-entity-relationship库:https://www.npmjs.com/package/ngrx-entity-relationship

你可以像这样创建选择器:

export const selectUserWithCompany = entityUser(
  entityUserCompany(),
);

然后在商店中使用它

this.store.select(selectUserWithCompany, 'userId');

得到

{
  id: 'userId',
  companyId: 'companyId',
  company: {
    id: 'companyId',
    // ...,
  },
  // ...,
}

【讨论】:

    猜你喜欢
    • 2018-03-01
    • 1970-01-01
    • 2017-08-30
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多