Динамическое представление загрузки контента

У меня есть компонент ember с шаблоном, который содержит таблицу. В моем компоненте - я хотел бы выдавать вызовы ajax стороннему сервису и получать некоторые данные. После получения этих данных мне нужно будет сделать еще один последующий вызов ajax на основе ввода. Так как это займет время, я хотел бы обновить представление один за другим, когда ajax вызвал окончание. В визуальном смысле - это будет добавление новой строки в таблицу после обработки одного запроса.

В настоящее время ember позволяет только передавать объект массива через его model() метод в роутере.

Я просмотрел несколько проектов, таких как List-view, но это не решает вышеупомянутую проблему.

РЕДАКТИРОВАТЬ:-

Ниже то, что я сейчас делаю -

import Ember from 'ember';
export default Ember.Route.extend({
    model() {
        var list = [];
        var promise = $.ajax({
            type: 'GET',
            url: 'thirdPartyService'
        });
        promise = promise.then(function(data){
            data = JSON.parse(data);
            return data[1];
        });
        promise.then(function(data){
            for (var i = 0; i < data.length; i++) {
                var idea = data[i];

                var url = "thirdPartyService";
                var secondPromise = $.ajax({
                    type: 'GET',
                    url: url,
                    dataType: "text"
                });
                secondPromise = secondPromise.then(function(data){
                    var result = x2js.xml_str2json(data);
                    return result;
                });
                secondPromise.then(function(data){
                    list.pushObject(item);
                });
                return secondPromise;
            }
        });
        return list;
    }
});

Мой шаблон

<tbody>
{{#each model as |idea|}}
  <tr>
    <td><input type="checkbox" name="id" value="{{idea.id}}"></td>
    <td>{{idea.field4}}</td>
    <td>{{idea.field5}}</td>
    <td>{{idea.field}}</td>
    <td>{{idea.field2}}</td>
    <td>{{idea.field3}}</td>
  </tr>
{{/each}}
</tbody>

Вид Ember будет отображаться при изменении списка. То, что я хочу сделать, это добавить строку в таблицу, когда list.pushObject(item); называется. В настоящее время - я вижу, что представление ждет, пока все не будет возвращено.

Кроме того, это приложение представляет собой электронное приложение - из-за этого у меня нет бэкэнда, например, и я не использую ember-data. Я звоню в несколько сторонних сервисов, так что в этом нет никаких моделей.

1 ответ

Решение

Обновить:

Демонстрация: https://ember-twiddle.com/eb79994c163dd1db4e2580cae066a318

В этой демонстрации я загружаю ваши данные с github и список репозиториев, так что ловушка модели будет возвращена, когда оба вызова API вернутся... и, наконец, она предоставит список имен репо.

С помощью loading.hbs сообщение о загрузке появляется автоматически до тех пор, пока не будут решены обещания модели.

В вашем коде перезапись переменной обещания, вероятно, не лучший подход, поскольку вы перезаписываете переменную, которая еще не разрешена.

Если вы хотите улучшить взаимодействие с пользователем, лучше всего, если у вас есть только один вызов ajax в модели и вы возвращаете это обещание... так что ваша модель содержит первый результат обещания... и вы можете использовать эти данные для выполнения обещания в контроллере и загрузите список, чтобы пользователь мог видеть заголовок таблицы и сообщение о загрузке до загрузки списка.

Демо дополнено второй страницей: https://ember-twiddle.com/eb79994c163dd1db4e2580cae066a318


Если вам нужно иметь дело с несколькими моделями на вашей странице, я бы скачал их в обработчике маршрута, с RSVP.hash,

// for example: app/routes/books.js, where books are the main model
import Ember from 'ember';

export default Ember.Route.extend({

  model() {
    return Ember.RSVP.hash({
      books: this.store.findAll('book'),
      authors: this.store.findAll('author'),
      libraries: this.store.findAll('library')
    });
  },

  setupController(controller, model) {
    const books = model.books;
    const authors = model.authors;
    const libraries = model.libraries;

    this._super(controller, books);

    controller.set('authors', authors);
    controller.set('libraries', libraries);
  },
});

В приведенном выше примере у вас есть model (со списком книг), authors а также libraries в вашем контроллере, так что вы можете передать эти массивы компонентам.

Используете ли вы Ember Data для доступа к API вашего сервера или стороннему сервису? В этом случае вы можете ввести store Служба в вашем компоненте и использовать там, как вы использовали бы в обработчике маршрутов.

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

В следующем примере мы создаем автономный компонент, где у вас есть кнопка для запуска действия, которое будет загружать данные с сервера, используя классический вызов jquery ajax, который заключен в обещание, так что вы можете связать эти обещания и уволить их в ряд.

Создать компонент

$ ember g component my-component

Шаблон app/templates/components/my-components.hbs, с кнопкой, флагом и списком.

<button {{action 'downloadSomething'}}>Download</button>

in progress: {{downloadInProgress}}

{{#each downloaded as |item|}}
  {{item.name}}
{{/each}}

Подключенный JS-файл app/components/my-components.js

import Ember from 'ember';

const { $ } = Ember;

export default Ember.Component.extend({

  downloaded: [],

  actions: {

    downloadSomething() {
      this.set('downloadInProgress', true);

      this._getData('http://localhost:8080').then(
        (response) => {
          this.set('downloadInProgress', false);
          this.get('downloaded').pushObjects(response.contacts);
        },
        (error) => {
          // some error handling...
        }
      );
    }
  },

  // this function wraps the ajax call in a Promise
  _getData(url) {
    return new Ember.RSVP.Promise((resolve, reject) =>
      $.ajax(url, {
        success(response) {
          resolve(response);
        },
        error(reason) {
          reject(reason);
        }
      })
    );
  }

});

В ответе ajax мы помещаем возвращенные объекты в downloaded массив, поэтому он всегда будет добавлен в список.

Другие вопросы по тегам