2

我正在使用秋田作为我的 Angular 应用程序的状态存储。

我成功地从后端服务器获取数据并填充我的商店(数据显示在组件中)但是当我尝试更新商店中的实体时,它会发出一个空对象。

我怀疑这对我对秋田的理解很重要,但我希望调用以下内容

  1. 使用给定 ID 更新实体
  2. 使用更新的实体触发 myQuery.select(id).subscribe()
     myStore.setActive(idOfThingToUpdate)
     myStore.updateActive({someProperty: newPropertyValue})
     myStore.removeActive(idOfThingToUpdate)

我也在服务中尝试过这种语法:

        this.myStore.update(entityId, {propertyName: newPropertyValue});

上面显示的订阅函数返回一个空对象。如果我在我的实体类中创建一个构造函数并设置几个默认值,那么在 query.select() 调用中只会返回构造函数中定义的那些属性。并且这些属性的值是默认值(在构造函数中定义)而不是存储中存在的值。

因此,以下一项或两项似乎是正确的:

  • 商店中的实体未更新
  • 秋田正在返回一个新构建的实体,而不是我所期望的(来自商店的更新实体)

希望一切都有意义....

一些代码:

服务:

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 时,这确实会返回有意义的数据:

@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); 
      });
    }
  }
4

1 回答 1

1

好吧,我找到了一个解决方案,不确定我是否完全理解它,但在这里......

在我的服务中,我有一个函数可以通过 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);
        });

现在这似乎像我最初预期的那样工作,并且 query.select/get 函数在我使用 update(id, object) 更新对象后返回更新的数据。

我大概可以使用 upsertMany([]),但我不确定它与 set([]) 的功能有何不同。实际上,使用 upsertMany 并传递一个 Contest 数组会以与 set([]) 相同的方式失败。所以现在我将依次为每个人坚持 upsert(id, entity) 。

当我告诉 Akita 应该提取 Contest 对象中的 id 字段并将其用作 ID 时,也许我错过了一步?

https://datorama.github.io/akita/docs/entities/entity-store

于 2020-08-28T00:00:44.490 回答