2015-03-11 3 views
0

Я использую Backbone и у меня есть следующие модели и коллекцииЛучший способ для визуализации коллекции в Backbone

App.Models.Person = Backbone.Model.extend({ 
}); 

App.Collections.People = Backbone.Collection.extend({ 
    model: App.Models.Person, 
    url: 'api/people', 
}); 

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

App.Views.PeopleView = Backbone.View.extend({ 
    el: $(".people"), 

    initialize: function() { 
     this.collection = new App.Collections.People(); 

     //This seems like a bad way to do it? 
     var that = this; 
     this.collection.fetch({success: function(){ 
      that.render(); 
     }}); 
    }, 

    render: function() { 
     var that = this; 
     _.each(this.collection.models, function (item) { 
      that.renderPerson(item); 
     }, this); 
    }, 

Я довольно новый для Backbone, но присвоить this на другой переменный, я использую его в функции успеха просто кажется плохим способом делать что-то? Любая помощь в передовой практике будет оценена по достоинству.

+0

вы сделаете это более сложным, чем необходимо, так как ваш обратный вызов не сверлит подзаголовок, prop или сделать что-нибудь условное, поэтому вы можете просто сказать '_.each (this.collection.models, this.renderPerson, this)' – dandavis

ответ

1

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

initialize: function() { 
    this.collection = new App.Collections.People(); 
    this.listenTo(this.collection, "sync", this.render); 

    // Fetch the initial state of the collection 
    this.collection.fetch(); 
} 

... настроит вашу коллекцию так, что она будет всегда вызывать this.render() всякий раз, когда происходит sync.

The docs on Backbone Events являются краткими, но довольно хорошими. Имейте в виду несколько вещей:

  • метод используется для регистрации слушателей событий (т.е. listenTo или on) изменения, как вы обеспечиваете контекст вызываемой функции. listenTo, например, будет автоматически использовать текущий контекст; on не будет. This piece of the docs объясняет это довольно хорошо.
  • Если вам нужно удалить представление, вам необходимо отключить прослушиватели событий. Самый простой способ сделать это - использовать listenTo для их соединения в первую очередь; то при уничтожении представления вы можете просто позвонить view.stopListening().

Для рендеринга есть много предложений о том, как это сделать. Как правило, иметь возможность отображать каждую отдельную модель является одним из способов. Вы также можете использовать Backbone.Collection#each для итерации по моделям и контролировать объем функции итерации. Например:

render: function() { 
    this.collection.each(function(model) { 
     var view = new App.Collections.PersonView({ model: model }); 
     view.render(); 
     this.$el.append(view.$el); 
    }, this);  
} 

Обратите внимание второй аргумент .each определяет область итератора. (Опять же, взгляните на the docs on controlling scope.Если вы предпочтете получить поддержку каркаса с рендерингом, ознакомьтесь со статьями CollectionView и ItemView.

+0

Спасибо за ваши ответы, хотя, когда я добавляю 'this.listenTo (this.collection," sync «this.render);« моя функция рендеринга не была вызвана. Мне пришлось сначала вызвать метод выборки – Bender

+0

А-а - извините, что не разъяснял это! Событие «sync» запускается всякий раз, когда коллекция синхронизируется с сервером.Это произойдет, когда 'fetch()' завершится асинхронно, поэтому вам нужно явно вызвать выборку. Если этот ответ достаточно хорош, подумайте о его принятии. Повеселись! –

+0

Отредактирован ответ, чтобы включить вызов 'fetch()'. –

0

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

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