Ember.js调用暴雪双API关联物品时出现DS.PromiseObject错误求助
<DS.PromiseObject:ember71726>的问题 咱们先理清楚你遇到的问题:为啥所有者字段显示正常,但物品名称却跳出这个Promise对象的提示?其实核心原因是Ember Data的关联关系默认是异步加载的,加上你模板里还有个小笔误,咱们一步步来修复:
问题出在哪?
首先看你模板里写的是{{auction.items.name}},但你的auction.js模型里定义的关联是item: DS.belongsTo('item')——是单数的item不是复数items,这是第一个小错误。
其次,就算改对成auction.item.name,因为belongsTo默认是异步的,Ember不会直接给你物品模型,而是返回一个DS.PromiseObject(相当于一个还在加载的占位符),直接访问.name就会显示这个对象的toString结果,也就是你看到的那段奇怪的字符串。
具体修复步骤
1. 先修正模板里的字段名
把{{auction.items.name}}改成{{auction.item.name}},对应模型里的单数关联字段。
2. 处理异步关联的两种方法
方法一:用await模板助手(推荐,Ember 3.16及以上支持)
在模板里用await来等待Promise加载完成,这样就能拿到物品名称了:
{{#each model as |auction|}} <ul> <li>{{await auction.item.name}}</li> <li>{{auction.quantity}}</li> <li>{{auction.bid}}</li> <li>{{auction.buyout}}</li> <li>{{auction.timeLeft}}</li> <li>{{auction.owner}}</li> </ul> {{/each}}
方法二:把关联改成同步加载(适合特定场景)
如果你确定加载拍卖数据时,物品数据已经在store里,或者愿意同步等待物品请求完成,可以修改auction.js模型,把关联设为同步:
// model/auction.js import DS from 'ember-data'; export default DS.Model.extend({ auc: DS.attr('number'), item: DS.belongsTo('item', { async: false }), // 加上{ async: false } owner: DS.attr('string'), });
⚠️ 注意:这种方式如果物品数据还没加载,Ember会同步发起请求,可能会阻塞页面渲染,所以更推荐用第一种await的方式。
3. 修正Item序列化器的格式
你的item序列化器之前的处理有点问题,没有按照Ember Data要求的JSON:API格式返回数据,导致关联可能无法正确解析。改成下面这样:
// serializers/item.js import DS from 'ember-data'; export default DS.JSONSerializer.extend({ normalizeResponse(store, primaryModelClass, payload, id, requestType) { const normalizedData = { data: { id: payload.id, type: 'item', attributes: { name: payload.name, description: payload.description, icon: payload.icon } } }; return this._super(store, primaryModelClass, normalizedData, id, requestType); } });
这样Ember Data就能正确识别物品模型的属性和类型了。
额外小技巧
可以给模板加个加载状态提示,提升用户体验:
<li>{{#if auction.item.isPending}}加载中...{{else}}{{auction.item.name}}{{/if}}</li>
另外记得检查网络请求,确保item的API能正常返回数据,格式和你提供的示例一致~
内容的提问来源于stack exchange,提问作者Cas

