【问题标题】:Ember - object related item lost on page reloadEmber - 页面重新加载时丢失的对象相关项目
【发布时间】:2019-05-23 15:43:37
【问题描述】:

我在 Ember 中有 Order 和 PaymentMethod 模型,它们具有多对一的关系,如下所示:

order.js

export default DS.Model.extend({
    paymentStatus: DS.attr('number', { defaultValue: 1 }),
    paymentMethod: DS.belongsTo('payment-method'),
})

payment-method.js

export default DS.Model.extend({
    name: DS.attr('string'),
    orderPaymentMethods: DS.hasMany('order')
})

订单已保存到数据库中 - 一切正常。然后我有一个路由审查订单,它获取订单模型(我的 API 只返回当前登录用户的订单模型)

review-order.js

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}}

这很好用,我在创建订单后过渡到审查订单路线 - 它会打印付款方式的名称。但是,如果我刷新review-order页面,这个就丢失了,我也不知道为什么!

【问题讨论】:

  • 您是否将 ember-cli-mirage 用于您的开发环境?如果是这样,那是因为海市蜃楼,它会在浏览/页面刷新时刷新。
  • @Bhabani Panigrahi - 抱歉我应该说清楚,不要使用 Django Rest Framework
  • 服务器在 GET /api/orders 上返回什么? paymentMethod 字段是否填写?
  • @DmytroKalinin review-order route的模型可以登录后从user对象获取数据,也可以调用api/order。执行后者然后会给我多个 ID 为空值的订单项。 (我将不胜感激任何帮助理解为什么会发生这种情况!)所以,我正在使用用户对象方法。我包括用户的订单、订单项目和订单付款方式。在我的回复中,包含的有效负载和数据关系中存在正确的数据。这里没有足够的空间 - 我们可以开始聊天吗?
  • 最后,我在 Django 的响应中创建了一个额外的字段,这是一个用于支付方式 (paymentMethodField) 的嵌套对象,我可以在模板中直接引用它作为 model.paymentMethodField.name 示例跨度>

标签: ember.js ember-data


【解决方案1】:

感谢您提供完整而详细的问题!我将尝试一个答案,但我没有 100% 的信息,我需要确保这会针对您的确切情况回答问题,但希望它仍然有用,您可以从中提取您需要的信息.

您提到的整体问题,即数据在刷新时未正确完全加载,可能是由于 API 响应没有包含它需要的所有信息。如果您检查 chrome 上的 Web 开发工具,您将能够验证是否是这种情况。

如果您打开开发工具,打开网络选项卡并找到正在加载您的数据的查询,那么我们可以验证这一点。我不知道您对开发工具有多熟悉,但如果您打开它们并刷新页面,您将看到浏览器发出的所有请求。然后您可以按 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 中包含付款方式。


关于您的示例,我注意到的另一件事是您在 review-order.js 路由中的 model() 钩子似乎有点不合常规 ?当我浏览此示例时,我在 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()钩子:

  model(params) {
    return this.store.findRecord('order', params.id, { include: 'payment_method'})
  }

我希望这可以帮助您解决问题?


这个问题是作为“我可以问一个问题”第 2 季第 4 集的一部分回答的。如果您希望看到我们完整地讨论这个答案,您可以在此处观看视频:https://www.youtube.com/watch?v=W1udsGt8F9g

【讨论】:

  • 非常感谢您回复这个非常全面的答案!如果你愿意,我可以准确地告诉你我在做什么,以及我从我的 API 中得到的响应。如果您想就此开始聊天,请告诉我
  • 是的,如果你想更直接地讨论这个问题,我在 Ember 社区 Discord 上。您是否尝试过我在答案中建议的任何事情?他们有帮助吗?
  • 感谢您回来。我在页面刷新时得到了正确的响应 - 所需的关系和包含的数据对我来说看起来是正确的 - 所以我确实需要更全面地调查这一点。
猜你喜欢
  • 2015-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多