2013-02-22 2 views
2

У меня есть модель, которая описывает организацию и подсерию, которая описывает разрешения для организации.Как я могу управлять извлечением данных для двух разных моделей перед визуализацией представления?

На мой взгляд, мне нужно получить данные из обеих моделей перед рендерингом. Когда я привязываю метод рендеринга представления к одному событию (например, model.change или subcollection.sync), есть моменты, которые мой экран отображает до того, как мои модели заполняются, что приводит к ошибке.

Вот соответствующая часть моего кода:

this.model = new OrgModel({id: id}); 
    this.model.permissions = new PermissionsCollection({org: id}); 

    this.model.permissions.on("sync", this.render); // SOMETIMES GETS CALLED BEFORE model:sync GETS CALLED 

    this.model.permissions.fetch({error: Utils.apiError}); 
    this.model.fetch({error: Utils.apiError}); 

Я не уверен, какое событие назвать «визуализацией» - потому что времена, которые каждый запрос возвращается первым.

Есть ли способ связать события синхронизации с тем, чтобы при вызове model.fetch он, в свою очередь, вызывал subcollection.fetch и не передавал событие sync, пока не будет выбран субколлекция: sync называется?

+0

Я предполагаю, что я мог бы сделать выборку последовательный, например, так: this.model.permissions.fetch ({ успех: функция() {this.model.fetch ({ошибка : Utils.apiError})}, error: Utils.apiError }); Не уверен, что это лучший способ –

+1

[Магистраль - выполнение множественной выборки() перед рендерингом вида] (http://stackoverflow.com/a/14963041/557612) – steveax

ответ

0

Это, вероятно, не самый лучший способ сделать это, но я обычно обрабатывают с помощью:

  • Добавление функции успеха после загрузки вашей модели коллекции. Каждая функция инициализирует переменную, такую ​​как this.permissionsFetched = true;
  • Изменение визуализации() так, чтобы ваш вид или его часть отображались, если переменные this.permissionsFetched и this.modelFetched были инициализированы.

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

Он не чувствует себя 100 % чистой, и может быть лучший способ сделать это. Однако он работает нормально для меня, и это немного лучше, чем делать ваши выборки серийными.

+0

Спасибо - однако это подтолкнуло бы мое состояние гонки вниз к рендерингу (например, если основная часть моей страницы не отображается, но подзаголовок, который использует коллекцию, готов, это приведет к проблемам с обработкой) –

+0

ну, не обязательно. В моем ответе не было ясно, читайте вместо этого: изменение render(), чтобы ваше представление отображалось только в том случае, если инициализированы переменные 'this.permissionsFetched' и' this.modelFetched'. Результат первой выборки будет вызывать render(), но представление не будет отображаться, потому что условие еще не будет выполнено. – AntonyG

+0

В качестве альтернативы вы также можете использовать значения по умолчанию для создания «пустой» модели, позволяющей визуализировать представление ([http://backbonejs.org/#Model-defaults](http://backbonejs.org/#Model- defaults)) без атрибутов модели, а затем обновляется позже, когда модель извлекается. – AntonyG

0

Как мне справиться с этим с помощью счетчика, чтобы отслеживать, сколько запросов в настоящее время на рассмотрении:

  • На request счетчик увеличивается
  • На sync или error счетчик декрементируется
  • Когда счетчик идет от 0 до 1, я стреляю loading Событие
  • Когда счетчик отправляется от 1 в 0, я огнь loaded события

можно реализовать систему, как это и связать вашу render функции к loaded события.

3
var deferred1, deferred2, that = this; 
this.model = new OrgModel({id: id}); 
this.model.permissions = new PermissionsCollection({org: id}); 
deferred1 = this.model.permissions.fetch({error: Utils.apiError}); 
deferred2 = this.model.fetch({error: Utils.apiError}); 

$.when(deferred1, deferred2).then(function(){ 
    that.render(); 
}); 

Существует очень сильная концепция отложенных и обещаний. Еще по теме можно прочитать на api.jquery.com/jQuery.Deferred