@ Ngrx/store:如何查询具有关系的模型 [英] @Ngrx/store: how to query models with relationships
问题描述
我是一个使用Redux的Angular 2应用程序(带有@ ngrx/store),我以这种方式对商店进行了建模:
I an Angular 2 app using Redux (with @ngrx/store), I have modeled the store this way:
{
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(一对多).我可以做这样的事情吗?
Basically, I have 2 types of objects: modelA and modelB. This is ok for now. But I can't find which is the best way to write a relationship between then, representing something like modelA has many modelB (one-to-many). Can I do something like this?
modelAmodelB: {
entities: {
1: [5],
2: [8, 9]
}
}
这是商店的根目录,不是'modelA'的子级. 这可能有效,但是如何使用@ ngrx/store方法从特定的modelA中查询" modelB?因为如果我编写一个选择器函数来读取全局状态并从modelAmodelB返回部分状态,则在编写函数时我无权访问其余状态.示例:
This is in the root of the store, it's not a child from 'modelA'. This might work, but how then would I 'query' the modelB from a specific modelA, using @ngrx/store methods? Because if I write a selector function that reads the global state and returns the partial state from modelAmodelB, I don't have access to the rest of the state when I compose my functions. Example:
compose(getModelAEntities(number[]), getModelAModelBRelations(modelA_id: number), getModelAModelBState() );
我可以使用Observable.combineLast
I can query this using 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相关的对象.
But I don't know if this is right: anytime I change modelA entities object (adding a new one, for example), the subscribe() is called, but the output is the same, because neither modelA entity has changed nor its modelB related objects.
PS:我可以这样查询
PS: I could do the query this way
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)
})
但是我不知道这是否是最好的方法.
But I don't know if this is the best approach.
推荐答案
我在同样的问题上苦苦挣扎,并提出了包装器的解决方案.
I was struggling with the same issue and came up with a solution of wrappers.
请查看ngrx-entity-relationship
库: https://www. npmjs.com/package/ngrx-entity-relationship
您可以创建类似的选择器:
you can create selectors like that:
export const selectUserWithCompany = entityUser(
entityUserCompany(),
);
然后在商店中使用它
this.store.select(selectUserWithCompany, 'userId');
获得
{
id: 'userId',
companyId: 'companyId',
company: {
id: 'companyId',
// ...,
},
// ...,
}
这篇关于@ Ngrx/store:如何查询具有关系的模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!