Введение в модели и коллекции Backbone и предоставление пользователю возможности создавать сообщения в блогах в веб-приложении в стиле «блог».
СФЕРА
Вы должны быть знакомы с областью видимости переменных. Например, переменная, созданная внутри функции, является локальной для этой функции. Переменные, не объявленные в функции, являются глобальными переменными. Давайте рассмотрим пример:
var whatever = "global"; // declared outside a function-global var functionOne = function() { var whatever = "local"; // declared within functionOne - local }; console.log(whatever); // result -> 'global'
В приведенном выше примере показано, что, хотя у нас есть две переменные с одинаковым именем, при входе в консоль вызывается только глобальная переменная. Но что, если мы войдем в консоль внутри functionOne ()?
var whatever = "global"; // declared outside a function-global var functionOne = function() { var whatever = "local"; // declared within functionOne - local console.log(whatever + " I'm inside functionOne!"); }; functionOne(); // result -> 'local I'm inside functionOne!'
При взаимодействии с переменными внутри функций локальная переменная всегда будет иметь приоритет.
Если вам нужно больше указаний по области видимости переменных, прочтите Главу о функциях из Eloquent JavaScript.
Цель этой части - объяснить вам, что такое все это «что бы то ни было». Давайте посмотрим, например, на DashboardView:
var DashboardView = Backbone.View.extend({ template: Handlebars.compile( $("#dashboard-view-template").html() ), initialize: function () { this.render(); // <-- WHAT DOES 'THIS' MEAN!?!?!? }, render: function () { this.$el.html(this.template({greeting:"This will display a list of our blog posts"})); // <-- AND IT'S HERE TOO! :( } });
Помните из части 1, что каждое представление в Backbone имеет функцию рендеринга. Когда мы инициализируем представление (и мы знаем, что функция инициализации любого представления выполняется всегда - никакая другая функция не будет делать этого без явного вызова), мы немедленно вызываем this.render ();
«Это» означает это представление. Итак, что такое вид? В части 1 я говорил вам, что представление - это объект, вот и все. Вы можете ссылаться на свойства в представлении, используя this. Инициализация - это свойство, рендеринг - это свойство - их значения просто являются функциями.
Поскольку вы работаете внутри функции, вы работаете в рамках этой функции.
Итак, внутри initialize () вы не можете просто вызвать render () - вы получите сообщение об ошибке, у initialize () нет render (), а render () представления выходит за рамки инициализировать (). Вместо этого вы говорите this.render (), потому что в view есть render (). По сути, вы говорите: «Мне нужно, чтобы здесь выполнялась функция рендеринга этого представления».
Понятно? Прохладный. Не позволяй этой маме разозлить вас. Со временем становится легче (как твоя мама).
Собственно, и последнее:
render: function () { this.$el.html(this.template({greeting:"This will display a list of our blog posts"})); // <-- let's talk about this 'this' }
В части 1 я объяснил, что каждое представление поставляется с элементом DOM. В приведенном выше render () я имею в виду этот элемент DOM, говоря this. $ El.html. По сути, он говорит: «HTML-элемент DOM этого представления должен быть шаблоном этого представления».
Ух, мне кажется, я все это объяснил как чушь. Оставьте мне комментарий с вопросами по этому поводу, и я постараюсь ответить как можно более подробно.
В ОБЩЕМ, «ЭТО» ПРОСТО ОЗНАЧАЕТ «ЭТО ВЗГЛЯД» ... вроде ... бывают случаи, когда это не означает, что ... Я объясню позже.
МОДЕЛИ И КОЛЛЕКЦИИ
Мне потребовалось невероятно много времени, чтобы осмыслить, что именно делают модели и коллекции и как они работают. Это потому, что я очень нетерпелив, и у меня никогда не было времени, чтобы понять это. Я объясню вам это самым простым языком:
var Blog = Backbone.Model.extend({ idAttribute: ‘blogId’ });
Это наша модель блога. В этом нет ничего особенного, и это сделано специально. Думайте о модели как о формочке для печенья. Формочка для печенья - это не печенье, но все печенья, которые вы сделаете из нее, будут иметь одинаковую форму. Каждый файл cookie является экземпляром формочки для печенья. Наша модель, Blog, - это форма для печенья, и она гласит: Каждый экземпляр меня можно отследить по его идентификатору blogId. Никакой другой информации он не предоставляет и не требует. (idAttribute предоставлен нам Backbone, проверьте это)
var Blogs = Backbone.Collection.extend({ model: Blog });
Это наша коллекция, Блоги. Опять же, здесь не так уж много. Коллекция - это просто коллекция экземпляров данной модели. Допустим, мы делаем 10 файлов cookie для блогов и помещаем их в коробку под названием «Блоги». Блок знает, где находится файл cookie, на основе идентификатора blogId этого файла cookie. Точно так же вы, как человек, желающий использовать файлы cookie для блога, знаете, в какое поле перейти (блоги) и какой конкретный файл cookie вам нужен.
Вы бы никогда не съели формочку для печенья и никогда не съели бы коробку. Но вы бы съели cookie (экземпляр модели) и вы бы съели cookie (набор этих экземпляров модели). В том же ключе вы не будете создавать несколько моделей блогов или коллекций блогов, вы просто создадите экземпляры модели блога по мере необходимости и поместите их в коллекцию.
Давайте разберемся с этим на практике. Вот наш новый app.js:
Сначала мы создали модель: Блог. Далее мы создали коллекцию: Блоги. Затем, в строке 9, мы сделали кое-что… другое. Мы создали несколько общих блогов. Я режу пару печенек и кладу их в коробку.
В строке 9 я создал коллекцию Блоги и назвал ее блогами. blogs - это набор из двух сообщений в блогах с собственными идентификаторами blogId, blogTitle и blogBody.
Далее в строке 23 я назначил this.collection DashboardView блогам. В строке 29 я передал this.collection в наш шаблон. (this.collection.toJSON () просто позволяет нам работать с данными в шаблоне - по этой причине мы добавляем библиотеку JSON2 в библиотеки.)
Если вы обратили внимание, то уже догадались, что теперь нам нужно обновить наш шаблон, чтобы использовать theBlogs. Вот наш новый index.html:
Изменения начинаются в строке 28, я прокомментировал, чтобы помочь объяснить, что происходит. Прочтите комментарии.
Строка 39 знакомит вас с одним из встроенных помощников Handlebars, #each. Мы передали theBlogs в наш шаблон, мы знаем, что у нас есть две записи блога в этой коллекции, и мы знаем, что хотим отображать их на нашей панели инструментов, поэтому #each имеет здесь наибольший смысл. Все, что находится между {{#each}} и {{/ each}}, будет повторяться до тех пор, пока не достигнет конца theBlogs, в этом случае он выполняется дважды (theBlogs - это, в конце концов, совокупность всего двух моделей).
Идите вперед и откройте index.html в Chrome:
Выглядит хорошо! Молодец!
СОЗДАНИЕ ПУНКТОВ В БЛОГЕ
Мы понимаем, что такое модель и коллекция, и понимаем, как с ними работать, используя Handlebars для отображения значений их свойств. Давайте обновим index.html, чтобы мы могли печатать новые сообщения в блоге!
Наш шаблон «Создать блог» начинается со строки 55. Я прокомментировал его, но вы сможете рассказать, что происходит, без комментариев. Мы добавили поле ввода для заголовка (# blog-title), текстовое поле для тела (# blog-body) и кнопку отправки (.submit-button).
Причина, по которой я привожу идентификаторы этих элементов, заключается в том, что мы собираемся использовать jQuery для получения значений этих элементов. Позвольте мне показать вам, что я имею в виду, app.js:
Изменения начинаются со строки 35. На самом деле, технически строка 38 - вы увидите, что я назначил коллекцию CreateBlogView блогам. Таким образом, и DashboardView, и CreateBlogView совместно используют точно такую же коллекцию.
Найдите секунду, чтобы прочитать все комментарии, которые я добавил к этому представлению, вы сможете понять, что происходит, просто читая сверху вниз.
Я создал новое События: {}, это еще одна из тех забавных вещей, которые есть в каждом представлении Backbone, просто до сих пор у нас не было в нем необходимости. У нас одно мероприятие:
'click .submit-button' : 'createNewBlog'
«Когда нажимается кнопка, только внутри элемента DOM этого представления, с классом« submit-button », запускаем createNewBlog () этого представления».
Я мог бы сделать:
'click #submit-button' : 'createNewBlog'
Я действительно просто хотел показать, что вы можете использовать класс и / или идентификатор.
createNewBlog () выглядит очень большим, но это не так. Основная часть этого - просто присвоение переменных значениям, которые нам нужно ввести в новую модель блога: newBlog. Например, мы используем простой jQuery, чтобы найти, что пользователь ввел для заголовка:
var newBlogTitle = $('#blog-title', this.$el).val();
«Найдите элемент в элементе DOM этого представления с идентификатором blog-title». Потрясающий! Теперь давайте возьмем значение, введенное пользователем, и сохраним его в переменной с именем newBlogTitle ».
Довольно простые вещи, когда вы понимаете, что он делает!
Естественно, в строке 49 мы создаем экземпляр нового блога. Мы даем ему три свойства и подставляем переменные вместо их значений. Наконец, мы должны добавить этот новый блог в коллекцию, и мы делаем это в строке 59. Я записал пару вещей в консоль, чтобы показать вам, что модель создается (и поэтому вы можете увидеть идентификатор блога, который не отображается на панели управления), а коллекция увеличивается на 1.
Откройте index.html в Chrome. Создайте новый пост в блоге и просмотрите его на своей панели инструментов. Помните, что, поскольку мы просто запускаем JavaScript в браузере, каждый раз, когда вы обновляете свои блоги, будет выглядеть так, как будто их никогда не существовало.
Молодец! Разве не приятно что-то создавать !?
В части 3 мы рассмотрим параметры редактирования и удаления.
Спасибо за чтение!