2015-02-17 2 views
0

У меня есть эта проблема с BackboneJS, где у меня есть коллекция, которая извлекается. Сбор выборки спусковых выборок на всех моделях в ней, но модель выборку (или инициализации, сделайте ваш выбор) обычаем JQuery вызова по линииjQuery, позвоночник и выборка - ждать завершения?

fetch: function(options) { 
    $.getJSON('/my/uri/').success(function(data) { 
     processData(data); 
    }); 
} 

Проблема в том, что крючки коллекции событий делают мой данных, прежде чем все модели в коллекции будут загружены и обработаны (поскольку getJSON является асинхронным). Я могу видеть, как я буду делать это с помощью одной модели; Я нашел несколько ссылок на использование отложенных переменных. Какой здесь подход?

ответ

0

Путем выполнения этой задачи вместо модели предоставляется "parse" function. Эта функция получает необработанный ответ от сервера для дальнейшей обработки. Я думаю, что все, что вам нужно сделать в processData(...), может быть выполнено там вместо этого. Предполагая, что вы это делаете, вы должны быть в состоянии просто доверять Backbone, чтобы делать правильную вещь, чтобы получить модифицированный ответ в модели как атрибуты.

Так что ваша модель & коллекция может выглядеть примерно так:

var MyModel = Backbone.Model.extend({ 
    parse: function(response) { 
     // Do what you need to modify 
     var modified = modifyResponse(response); 
     return modified; 
    }, 

    // ... whatever else you need 
}); 

var MyCollection = Backbone.Collection.extend({ 
    model: MyModel, 

    url: '/my/uri', 

    // ... whatever else you need 
}); 

Нет необходимости переопределить fetch(...) и сделать что-нибудь слишком сумасшедший. Для того, чтобы получить данные с сервера, было бы то же самое, я предполагаю, что вы уже делаете:

var collection = new MyCollection(); 
collection.fetch(); 

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

1

Что вы делаете в fetch, просто загружаете файл JSON и передаете его в другое место. это не то, что дает выбор. , если вы хотите получить сами, вы должны установить (reset) данные в свою коллекцию и вызвать событие для eventlistener.

fetch: function(options) { 
    $.getJSON('/my/uri/').success(function(data) { 
     _result = doSomethingForTheData(data); 
     //this makes reset event 
     yourCollection.reset(_result); 
     //or you can make your custom event whatever you want. 
     yourCollection.reset(_result,{silent : true}); 
     yourcollection.trigger("yourCustomEventName",yourCollection); 
    }); 
} 

Но я думаю, что вы пытаетесь достичь не требует подмену fetch

в вашей коллекции

var YourCollection = Backbone.Collection.extend({ 
    url: 'my/uri' 
}); 

на ваш взгляд

yourCollection = new YourCollection(); 
yourCollection.fetch() 
yourView.listenTo(yourCollection,"sync",function(){ 
    this.refresh() 
    //or whatever you want with your updated Collection. 
}); 

Вы также можете использовать обратный вызов успеха AJAX для работы над методами, работающими асинхронно, как вы пытаетесь do.But Нет причин не использовать структуру соединительной связи с базовой сетью (event trigger/listen).

0

Я бы сначала рекомендовал вам использовать Api Backbone для ваших запросов XHR. Это сделает его более последовательным, а также сохранит «извлечения» родной для Backbone. Просто предложение ...

На ваш вопрос. У вас здесь пара вариантов. синхронизации апи с использованием Backbone в:

Пример модели: Использование «разобрать», как ваш звонок «ProcessData».

var MyModel = Backone.Model.extend({ 

    url: '/my/uri/', 

    //http://backbonejs.org/#Model-parse 
    parse: function(response) { 
     // this is your 'processData' call. Do your logic here. This is done before the consumer gets the data. 

     // return the correct object. 
     return response.Data; 
    } 

}) 

// Пример использования: Делайте то, что вам нужно сделать в успехе.

var myModel = new MyModel(); 
myModel.fetch() 
    .success(function(data){ 
     // this is the data AFTER parse has done it's magic. Do other view logic. 

    }); 

Вот пример использования его в представлении и подписки на событие «sync» на модели. ПРИМЕЧАНИЕ Вы должны вызвать выборку на модели.

var MyView = Backbone.View.extend({ 

    template: _.template(someHTMLTemplate), 

    initialize: function() { 
     // setup a sync event that will render once the model fetch is complete. 
     this.model = new MyModel() 
      .on('sync', this.render, this); 

     // this is just an example and I don't recommend putting fetch in initialize. 
     this.model.fetch(); 
    }, 

    render: function() { 
     this.$('.content').html(this.template({ 
      model: this.model.toJSON() 
     })); 
    } 
}); 

Я хотел бы избежать пользовательских триггеров как можно больше, поскольку они трудно поддерживать и легко получить из рук на больших команд, если все это не согласуется в именовании и использование!

И, наконец, если у вас есть несколько событий, которые необходимо выполнить перед представлением, то я бы использовал метод $ .when для отслеживания объектов обещания.

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