2013-01-03 3 views
1

Я работаю над приложением Backbone, и сложность возрастает. Одним из побочных эффектов является то, что иногда начальная загрузка страниц идет медленно. Я проследил эту проблему до ожидаемого запроса AJAX.Назначение отложенного объекта (jqxhr) модели или коллекции

В некоторых из моих текущих маршрутов я делаю что-то вроде 4 отдельных запросов. Некоторые из них важны, как загрузка шаблона. Поэтому я использую функцию done() из запроса jQuery ajax для передачи обратного вызова, который продолжает загрузку страницы.

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

Так вот мое предложение

var myModel = new Posts(); //instantiate the model 
myModel.dfd = myModel.fetch(); 

, а затем позже в смежном ракурсе, который обрабатывает сообщения элемента имеет метод, который получает модель передается и сделать что-то вроде этого

render : function() { 
    var self = this; 
    this.model.dfd.done(function() { 
    this.html(template(self.model.toJSON()); 
    } 
} 

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

Это хорошая идея?

+0

Не могли бы вы включить код, в котором инициализируется ваш вид, и вызывается метод 'render()'? – Lukas

+0

«Это хорошая идея?». Вы говорите нам. Это работает? –

+0

@ Beetroot-Beetroot да это прекрасно работает. Но пока не уверен, сколько из преимуществ производительности я получаю. – Daniel

ответ

0

Это будет полностью работать, и это отличный пример использования $.Deferred ... но есть и другой способ, который вы могли бы рассмотреть: просто сделайте запрос синхронным в первую очередь.

Fetch передает по своим опциям $.ajax и $.ajax принимает аргумент «асинхронный», который контролирует, является ли запрос синхронным или асинхронным. Это означает, что если вы выполните:

self.model.fetch({async: false}); 
// self.model will already be fetched by the time this next line runs 
this.html(template(self.model.toJSON()); 

В любом случае работает отлично ИМХО; какой стиль - это только вопрос предпочтения.

P.S. Одна незначительная заметка о более позднем стиле заключается в том, что у него могут быть проблемы, если вы попытаетесь объединить его с $ .Deferred. С сайта jQuery:

В отношении jQuery 1.8 использование async: false с jqXHR ($ .Deferred) устарело; вы должны использовать полные/успешные/обратные вызовы.

+2

«Установка этого параметра в значение false (и, таким образом, вызов более не асинхронный) настоятельно не рекомендуется, так как это может привести к тому, что браузер перестанет реагировать». - jQuery docs – Lukas

+0

Правильно, но если вы делаете «A», сделайте запрос, B) ничего не делайте до тех пор, пока запрос не вернется, C) снова сделайте материал », это по сути то же самое, что и« A », сделайте запрос, B) остановки страницы, C) снова делать вещи ". – machineghost

+0

http://api.jquery.com/jQuery.ajax/ – Lukas

2

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

Таким образом, они не могут видеть записи в блоге за долю секунды, которую требуется для их получения с сервера (продукт шаблона и вызов model.toJSON(), который просто возвращает {}). Затем, когда модель заполняет данные и запускает событие «изменения» (я предполагаю, что у вас есть представление, слушающее событие изменения модели и рендеринг при его возникновении), тогда он будет обновляться автоматически.

Я считаю, что самый изящный и естественный способ делать вещи в Backbone.js.Он оставляет код чистым, и он имеет дело с любым упорядочением операций просмотра и моделирования модели, не прибегая к специальному кодированию, чтобы попытаться выполнить операции.

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

+0

Это похоже на популярный подход в эти дни и в отношении удобства использования. например Facebook-мобиль сначала загрузит некоторый кешированный контент, пока он не получит новые обновления. То же самое с Instagram. – Daniel

Смежные вопросы