为什么 Akita statestore return 是一个空实体而不是更新后的实体?
Why does Akita statestore return an empty entity rather than updated entity?
我正在使用 Akita 作为我的 Angular 应用程序的状态存储。
我成功地从后端服务器获取数据并填充我的商店(数据显示在组件中)但是当我尝试更新商店中的实体时它发出一个空对象。
我怀疑这是我对秋田犬的理解所缺少的一些基本知识,但我希望调用以下内容
- 更新具有给定 ID 的实体
- 触发 myQuery.select(id).subscribe() 与更新的实体
myStore.setActive(idOfThingToUpdate)
myStore.updateActive({someProperty: newPropertyValue})
myStore.removeActive(idOfThingToUpdate)
我也在服务中尝试过这种语法:
this.myStore.update(entityId, {propertyName: newPropertyValue});
上面显示的订阅函数是 returning 一个空对象。
如果我在我的实体 class 中创建一个构造函数并设置几个默认值,则只有在构造函数中定义的属性才会在 query.select() 调用中被 return 编辑。这些属性的值是默认值(在构造函数中定义)而不是商店中存在的值。
所以似乎以下一项或两项为真:
- 商店中的实体未更新
- akita 是 return 一个新构造的实体,而不是我期望的(商店更新的实体)
希望一切都有意义....
一些代码:
服务:
this.contestStore.setActive(contestId);
// attempt set a single property 'winningLicence' on the active entity
this.contestStore.updateActive({
winningLicence: newWinningLicence
}
);
this.contestStore.removeActive(contestId);
我是要将新构造的实体传递到 updateActive() 函数还是只是传递我想要更新的道具?
export interface ContestState {
loading: boolean;
contests: Contest[];
}
export function createInitialState(): ContestState {
return {
loading: false,
contests: []
};
}
@StoreConfig({ name: 'contestStore', resettable: true})
export class ContestStore extends EntityStore<ContestState> {
constructor() {
super(createInitialState());
}
}
查询 - 当我在组件中调用 selectAll 时,这会 return 有意义的数据:
@Injectable()
export class ContestsQuery extends QueryEntity<ContestState> {
constructor(protected contestStore: ContestStore) {
super(contestStore);
}
}
来自组件...
ngOnInit(): void {
// contest is @Input and may be a new unsaved/no id contest, hence check
if (this.contest.id) {
this.contestsQuery.selectEntity(this.contest.id).subscribe((contest: Contest) => {
// this comes back as empty object after calling my update code in service shown above
console.log(contest);
});
}
}
好吧,我找到了一个解决方案,不确定我是否完全理解它,但它是...
在我的服务中,我有一个功能可以通过 HTTP 从后端获取数据来刷新缓存,然后迭代响应对象并调用 store.set() 来设置存储....
const contests = [];
contestData.forEach((json) => {
const contest = Object.assign(new Contest(), json);
contests.push(contest);
});
this.contestStore.set(contests);
我改为使用 upsert 而不是尝试使用 set() 函数一次性设置集合:
contestData.forEach((json) => {
const contest = Object.assign(new Contest(), json);
this.contestStore.upsert(contest.id, contest);
});
现在这似乎像我最初预期的那样工作并且查询。select/get 函数 return 在我使用 update(id, object) 更新对象后更新数据。
我大概可以使用 upsertMany([]),但我不确定这与 set([]) 在功能上有何不同。实际上,使用 upsertMany 并传递 Contest 数组会以与 set([]) 相同的方式失败。所以现在我会依次为每个人坚持 upsert(id, entity)。
也许我在告诉 Akita 应该提取 Contest 对象中的 id 字段并将其用作 ID 时错过了一步?
我正在使用 Akita 作为我的 Angular 应用程序的状态存储。
我成功地从后端服务器获取数据并填充我的商店(数据显示在组件中)但是当我尝试更新商店中的实体时它发出一个空对象。
我怀疑这是我对秋田犬的理解所缺少的一些基本知识,但我希望调用以下内容
- 更新具有给定 ID 的实体
- 触发 myQuery.select(id).subscribe() 与更新的实体
myStore.setActive(idOfThingToUpdate)
myStore.updateActive({someProperty: newPropertyValue})
myStore.removeActive(idOfThingToUpdate)
我也在服务中尝试过这种语法:
this.myStore.update(entityId, {propertyName: newPropertyValue});
上面显示的订阅函数是 returning 一个空对象。 如果我在我的实体 class 中创建一个构造函数并设置几个默认值,则只有在构造函数中定义的属性才会在 query.select() 调用中被 return 编辑。这些属性的值是默认值(在构造函数中定义)而不是商店中存在的值。
所以似乎以下一项或两项为真:
- 商店中的实体未更新
- akita 是 return 一个新构造的实体,而不是我期望的(商店更新的实体)
希望一切都有意义....
一些代码:
服务:
this.contestStore.setActive(contestId);
// attempt set a single property 'winningLicence' on the active entity
this.contestStore.updateActive({
winningLicence: newWinningLicence
}
);
this.contestStore.removeActive(contestId);
我是要将新构造的实体传递到 updateActive() 函数还是只是传递我想要更新的道具?
export interface ContestState {
loading: boolean;
contests: Contest[];
}
export function createInitialState(): ContestState {
return {
loading: false,
contests: []
};
}
@StoreConfig({ name: 'contestStore', resettable: true})
export class ContestStore extends EntityStore<ContestState> {
constructor() {
super(createInitialState());
}
}
查询 - 当我在组件中调用 selectAll 时,这会 return 有意义的数据:
@Injectable()
export class ContestsQuery extends QueryEntity<ContestState> {
constructor(protected contestStore: ContestStore) {
super(contestStore);
}
}
来自组件...
ngOnInit(): void {
// contest is @Input and may be a new unsaved/no id contest, hence check
if (this.contest.id) {
this.contestsQuery.selectEntity(this.contest.id).subscribe((contest: Contest) => {
// this comes back as empty object after calling my update code in service shown above
console.log(contest);
});
}
}
好吧,我找到了一个解决方案,不确定我是否完全理解它,但它是...
在我的服务中,我有一个功能可以通过 HTTP 从后端获取数据来刷新缓存,然后迭代响应对象并调用 store.set() 来设置存储....
const contests = [];
contestData.forEach((json) => {
const contest = Object.assign(new Contest(), json);
contests.push(contest);
});
this.contestStore.set(contests);
我改为使用 upsert 而不是尝试使用 set() 函数一次性设置集合:
contestData.forEach((json) => {
const contest = Object.assign(new Contest(), json);
this.contestStore.upsert(contest.id, contest);
});
现在这似乎像我最初预期的那样工作并且查询。select/get 函数 return 在我使用 update(id, object) 更新对象后更新数据。
我大概可以使用 upsertMany([]),但我不确定这与 set([]) 在功能上有何不同。实际上,使用 upsertMany 并传递 Contest 数组会以与 set([]) 相同的方式失败。所以现在我会依次为每个人坚持 upsert(id, entity)。
也许我在告诉 Akita 应该提取 Contest 对象中的 id 字段并将其用作 ID 时错过了一步?