


#10 — Вид коллекции.
Берем на вооружение вид коллекции.
Как вы помните, последний скринкаст был, о коллекции. Все уяснили, что это такое. Но как же рендерить всю эту коллекцию сразу, а не по одной модели ? Для этого и нужен вид коллекции. Не пугайтесь. Это тот же самый Backbone.View
, только с чуть другой логикой внутри метода render
Начальный код выглядит так
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
//Модель человека var Person = Backbone.Model.extend({ defaults: { name: 'Иван Петров', age: 40, job: 'слесарь' } }); var person = new Person(); //Список людей var PeopleCollection = Backbone.Collection.extend({ model: Person }); //Вид одного человека var PersonView = Backbone.View.extend({ tagName: 'li', template: _.template('<strong><%= name %></strong> ( <%= age %> ) - <%= job %>'), initialize: function() { this.render(); }, render: function() { //замечательный шаблон this.$el.html( this.template( this.model.toJSON() ) ); } }); var peopleCollection = new PeopleCollection([ { name: 'Петр', age: 20, job: 'Таксист' }, { name: 'Олег', age: 24, job: 'Менеджер' }, { name: 'Анна', age: 18, job: 'Студентка' } ]); |
Ближе к делу. Создадим наш вид списка людей
1 2 3 4 5 6 7 |
//Вид списка людей var PeopleView = Backbone.View.extend({ tagName: 'ul', initialize: function() { } }); |
В качестве tagName
, как не удивительно возьмем ul. Следом за созданием вида, давайте инициализируем его экземпляр и передадим в него нашу коллекцию.
1 |
var peopleView = new PeopleView({collection: peopleCollection}); |
Теперь самое интересное. Начнем рендер нашего вида коллекции. Для этого нам понадобится пройтись по коллекции и создать по виду, на каждую модель этой коллекции. После чего вставить каждый срендеренный вид, в элемент нашего списка ul. Напишем следующий код.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//Вид списка людей var PeopleView = Backbone.View.extend({ tagName: 'ul', initialize: function() { }, render: function() { this.collection.each(function(person) { var personView = new PersonView({model: person}); this.$el.append(personView.render().el); }, this); return this; } }); |
Как вы заметили, я использую цепной вызов метода render() и свойства el, один за другим. personView.render().el
Для того, чтобы это осуществить нужно в конце метода render , возвращать этот экземпляр вида return this
В PersonView, сделаем тоже самое, для удобства рендеринга и сразу же взятия каждого элемента вида.
1 2 3 4 5 6 7 8 9 10 |
//Вид одного человека var PersonView = Backbone.View.extend({ ... render: function() { //замечательный шаблон this.$el.html( this.template( this.model.toJSON() ) ); return this; } }); |
Теперь осталось только срендерить и вставить в документ, сам вид коллекции.
1 |
$(document.body).append(peopleView.render().el); |
Проверяем в браузере, если вы делали все верно, то увидите результат. Всем спасибо! И до скорых встреч на loftblog!
Оставь комментарий!
14 thoughts on “#10 — Вид коллекции.”
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.
С каждым уроком становится все более интереснее работать с backbone. Спасибо вам!
Внутри «вида списка людей», в методе render используется анонимная функция. в качестве её параметров вы передаёте «person» говоря, что этот персон берётся снаружи.
На самом деле всё не так. Посмотрите повнимательней в http://underscorejs.ru/#each , в качестве первого параметра передаётся значение, в качестве второго ключ итерации… То есть итерация происходит по «this.collection» но никак не по значению переменной person снаружи. Если я не прав то поправьте меня пожалуйста. Спасибо.
///беру слова обратно, при повторном просмотре я Вас понял иначе 🙂 (, а именно как описал выше)
Бывает)
нет, итерация идет по this.collection.models так как бекбоновские методы коллекций оборачивают андескоровские таким образом, чтобы они ссылались на их модели.
Здравствуйте, помогите пожалуйста у мене выдает ошибку «TypeError: Cannot call method ‘each’ of undefined» я не могу разобраться в чём проблема. Код брал с вашего примера.
var person = new Person(); — на 9 минуте не делает ничего
Объясните, пожалуйста! Не могу понять, зачем в методе each мы в конце передаем в качестве второго параметра this?
чтобы сохранить контекст на саму коллекцию, а не на отдельный её элемент (как будет при использовании перебора через each по умолчанию, без этого параметра).
Спасибо, теперь понял)
подскажите пожалуйста зачем в представлении коллекции строка: this.$el.append(personView.render().el);
насколько я понял при переборе коллекции на каждую модель создается новое представление модели а потом в указанной мной строке запускается render этой же модели.
но render представления модели и так запускается при ее инициализации, получается мы запускаем его дважды
могу предположить, что когда будем прослушивать события, придется рендорить заново.
А в начале получается что рендорим 2 раза. Может имеет смысл при инициализации не рендорить
P.s. при использовании ‘use strict’, если в each function не передать this, то будет undefined, а не windows объект
До этого работал с PHP, с JS знаком только в контексте выборок Jquery… вроде понятно что происходит в видео, делаю параллельно на localhost, но начинаю уже запутываться в этих вызовах и функциях =)
Есть вопрос, почему во внешнем документе работает
$(document.body).append(peopleView.render().el);
Но в main.js не работает
index.html и main.js сохранены в utf-8
в index.html прописано:
$(‘body’).append(peopleView.el);
При выводе вида коллекции, вместо русских букаф
ромбики с вопросиками.
Как решить проблему?