我有一个RPG制作系统的申请。我有一条路线用于用户的当前库存(库存路线),另一条路线供用户收集物品并最终将其放入库存(这称为收集路线)。每当我从Inventory路线导航到Gather路线或反之亦然时,我都会看到此错误。这似乎与我在收集路线的模型挂钩中加载的项目模型有关:
> Uncaught (in promise) Error: Assertion Failed: You attempted to update
> `length` on `item:common_curative_reagent
> (@ember-data:lid-item-common_curative_reagent),item:common_poisonous_reagent
> (@ember-data:lid-item-common_poisonous_reagent),(...)`, but it had
> already been used previously in the same computation. Attempting to
> update a value after using it in a computation can cause logical
> errors, infinite revalidation bugs, and performance issues, and is not
> supported.
`length` was first used:
Stack trace for the update:
at dirtyTagFor (validator.js:575)
at markObjectAsDirty (index.js:546)
at notifyPropertyChange (index.js:584)
at arrayContentDidChange (index.js:691)
at replaceInNativeArray (index.js:759)
at Array.replace (array.js:1730)
at Array.pushObjects (array.js:1452)
从我对无限重新验证错误的研究来看,我认为这与Glimmer跟踪属性在同一计算中被引用有关,也可以修改它。在这种情况下,跟踪属性似乎是我在Gather路由中加载的项目列表(用户可以收集的项目列表),但这个列表必须存在于我无法访问的框架中?
库存模型挂钩:
async model()
{
let user = this.session.getUser();
let inventory = await this.inventory.getInventory();
if (isEmpty(inventory?.ingredients)) { return []; }
let items = RSVP.all(Object.entries(inventory.ingredients).map(([itemID]) => { return this.store.findRecord('item', itemID) }));
let model = RSVP.hash({
"items": items,
"user": user,
"inventory": inventory
});
return model;
}
这个错误似乎与下面的代码有关,因为如果我将其注解掉并返回空列表,则不会发生这种情况。收集模型挂钩:
async loadGatherItems(gatherAry)
{
// Search through the gather table columns and get a list of all possible items
let promises = [];
gatherAry.toArray().forEach((gatherRecord) =>
{
if (isEmpty(gatherRecord?.items)) { return; }
gatherRecord.items.forEach((itemGroup) =>
{
if (isEmpty(itemGroup?.item)) { return; }
let itemID = itemGroup.item;
promises.push(this.store.findRecord("item", itemID));
});
});
let gatherItems = await RSVP.all(promises);
// Also include any 'trivial' item
let trivials = await this.store.query("item", {
"orderBy": "rarity",
"equalTo": 'trivial'
});
trivials.forEach((item) => { gatherItems.push(item); });
return gatherItems;
}
尽管出现了错误,但应用程序本身似乎运行良好。正如我所说的,当我分别加载Inventory或Gather路由时不会发生这种情况,但只有当我从一个切换到另一个时才会发生。它只发生一次(例如,如果我不断来回切换,我只会看到一次错误)。
如果在这两个路由之间切换之前加载Items路由,则不会发生错误…Items路由在Item模型上执行findAll。事实上,如果我在库存路线的顶部添加一个findAll,错误就不会发生。不过,我不想保留这一点,因为我不需要在库存路线中加载所有可能的物品——我只需要库存中的物品。
我仍然在学习Ember和JS,所以如果能帮助解释为什么会发生这种情况,我将不胜感激!
编辑1
我仍然不知道为什么会发生这个错误,但这肯定与我将Items加载到商店的方式有关。当我切换路线时,使用findRecord获得的任何新项目都会导致出现错误-如果该项目已经在商店中,则不会导致出现错误。这就是为什么在我的模型挂钩顶部执行findAll会导致错误消失的原因。
1条答案
按热度按时间qhhrdooz1#
最终,错误来自对多个尚未加载到存储中的ID调用findRecord。与其在循环中调用findRecord,我应该尝试进行某种单一网络查询,以获得尽可能小的包含列表,然后在客户端对其进行精简。
我不知道这方面的最佳实践,也不知道为什么会发生错误(或者是否应该发生错误?)。一方面,我试图通过只请求我知道我需要的ID来限制从服务器返回的数据量。另一方面,我正在权衡较小的数据集大小和更多的请求数量。
也许这只是我后端的一个限制,它不支持对一组特定ID(firebase)的查询。