Динамическое представление загрузки контента
У меня есть компонент 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
массив, поэтому он всегда будет добавлен в список.