我在Ember中拥有Order和PaymentMethod模型,它们具有多对一的关系,如下所示:
export default DS.Model.extend({
paymentStatus: DS.attr('number', { defaultValue: 1 }),
paymentMethod: DS.belongsTo('payment-method'),
})
export default DS.Model.extend({
name: DS.attr('string'),
orderPaymentMethods: DS.hasMany('order')
})
订单已保存到数据库-一切正常。然后,我有一个路线复审订单,该订单获得了订单模型(我的API仅返回当前登录用户的订单模型)
export default Route.extend({
model() {
const order = this.store.findAll('order', { include: 'payment_method' }).then((orders) => {
return orders.filterBy('paymentStatus', 1).get('lastObject');
});
return order;
}
});
在我的订单模板中,我像这样打印出付款方式关系
{{model.paymentMethod.name}}
这很好用,我在创建订单后过渡到复审订单路线-它打印付款方式的名称。但是,如果刷新查看顺序页面,则会丢失该信息,而且我也不知道为什么!
答案 0 :(得分:1)
感谢完整和详细的问题!我将尝试回答一个问题,但我没有100%的信息需要确保该信息可以根据您的实际情况回答该问题,但希望它仍然有用,并且您可以从中提取所需信息。
您提到的总体问题是刷新时未正确正确加载数据,这很可能是由于API响应没有所需的所有信息所致。如果您在chrome上检查了Web Dev Tools,则可以验证情况是否如此。
如果您打开开发工具,请打开“网络”标签并找到正在加载数据的查询,然后我们可以对此进行验证。我不知道您对开发工具有多熟悉,但是如果您打开它们并刷新页面,您将看到浏览器发出的所有请求。然后,您可以按XHR进行过滤以查找API查询:
然后,您可以单击有问题的请求,并使用预览标签浏览可用数据:
通过查看此数据,您将能够验证是否已建立所需的关系,并且您还将能够确定JSON:API的includes
部分中是否还包含正确的数据。响应。有关外观的示例,您可以查看examples page for the official JSON:API documentation
我们花了一些时间尝试使用Mirage复制您的问题,以便我们可以确切地显示您遇到的问题。这只是一个玩具示例,但它确实复制了错误并显示了我上面描述的方法如何解决了这个问题。
首先我完全按照您的描述复制模型,然后创建一个Mirage端点来处理获取单个订单的请求:
this.get('/orders/:id', (schema, request) => {
let responseData = {
data: {
id: request.params.id,
type: 'orders',
attributes: { 'payment-status': 1 },
relationships: {
"payment-method": {
data: { id: "42", type: "payment-methods" }
}
}
}
};
if(request.queryParams.include === "payment_method") {
responseData.included = [{
type: "payment-methods",
id: "42",
attributes: { name: "Credit Card" }
}];
}
return responseData;
});
您将看到,如果queryParams
包含?include=payment_method
,则可以确保付款方式包含在响应JSON中。
我注意到您的示例的另一件事是,您在model()
路由中的review-order.js
钩子看起来有点不合常规,当我浏览此示例时,我在{ {1}}路由,并确保在过渡到订单对象时我通过了订单对象。这是我的路由器定义:
review-order
然后,我使用Router.map(function() {
this.route('review-order', { path: '/review/:id'});
});
操作创建了一个简单的按钮来模拟创建订单:
createOrder()
如您所见,我将订单对象包含在 actions: {
createOrder() {
let paymentMethod = this.store.createRecord('payment-method', {
name: 'Credit Card'
});
let order = this.store.createRecord('order', {
id: 'not-null',
paymentStatus: 1,
paymentMethod: paymentMethod,
});
// we don't actually save because I don't have a backend setup correctly
// order.save().then(() => { })
// when we're done transition to review route with the model
this.transitionToRoute('review-order', order);
}
}
调用中。
然后,我们可以稍微简化一下您路线中的transitionToRoute()
钩子:
model()
我希望可以帮助您解决问题
该问题已作为“我可以问一个问题”第2季第4集的一部分得到回答。如果您希望我们全面讨论此问题,可以在此处查看视频:https://www.youtube.com/watch?v=W1udsGt8F9g