Ember - объект, связанный с предметом, потерян при перезагрузке страницы - PullRequest
0 голосов
/ 17 мая 2019

У меня есть модели Order и PaymentMethod в Ember с отношением многие-к-одному, например:

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

Это прекрасно работает. Я перехожу к маршруту заказа на рецензирование после создания заказа - он печатает название метода оплаты.,Однако, если я обновлю страницу заказа обзора, это будет потеряно, и я понятия не имею, почему!

1 Ответ

1 голос
/ 23 мая 2019

спасибо за полный и подробный вопрос!Я собираюсь попытаться ответить, но у меня нет 100% информации, которая мне понадобилась бы, чтобы быть уверенной, что это ответит на проблему для вашей конкретной ситуации, но, надеюсь, она все еще будет полезна, и вы сможете извлечь из нее то, что вам нужно,

Общая проблема, о которой вы упомянули, заключается в том, что данные не полностью загружаются при обновлении, вероятно, вызвано тем, что ответ API не содержит всей необходимой информации.Если вы проверите Web Dev Tools на Chrome, вы сможете убедиться, что это так.

Если вы откроете инструменты разработки, откроете вкладку сети и найдете запрос, который загружает ваши данные, тогда мы можем это проверить.Я не знаю, насколько вы знакомы с инструментами разработки, но если вы откроете их и обновите страницу, вы увидите все запросы, сделанные браузером.Затем вы можете выполнить фильтрацию по XHR, чтобы найти запрос API:

Chrome Dev Tools Network tab

После этого вы сможете щелкнуть соответствующий запрос и использовать вкладку preview для изучения доступных данных:

Chrome Dev Tools Data Preview

Просматривая эти данные, вы сможете проверить, установлены ли необходимые отношения, и вытакже сможет, если правильные данные также включены в раздел includes ответа JSON: API.Пример того, как это должно выглядеть, вы можете найти на странице примеров официальной JSON: документация API

Мы потратили немного времени, пытаясь воспроизвести вашу проблему, используя Мираж , чтобы мы могли показать точную проблему, с которой вы столкнулись.Это небольшой игрушечный пример, но он повторяет ошибку и показывает, как описанный выше метод решает проблему.

Сначала я реплицировал ваши модели в точности так, как вы их описали, затем я создал конечную точку 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 кажется немного нетрадиционным. Когда я просматривал этот пример, я использовал динамический сегмент на 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'})
  }

Надеюсь, это поможет вам разобраться в вашей проблеме ?


На этот вопрос ответили в рамках 4-го сезона 4-го сезона «Могу я задать вопрос». Если вы хотите, чтобы мы обсудили этот ответ полностью, вы можете посмотреть видео здесь: https://www.youtube.com/watch?v=W1udsGt8F9g

...