Backbone.js — это небольшая библиотека (уменьшенная до 5 КБ), которая позволяет создавать одностраничные веб-приложения. В отличие от многих своих коллег, Backbone не очень самоуверен в том, как вы его используете. Помимо некоторых основных концепций, дизайн вашего приложения остается на ваше усмотрение.
В этом уроке вы узнаете один из популярных шаблонов, который сообщество приняло во внимание: базовый шаблон . Мы будем использовать этот шаблон для создания простой библиотеки книг, которую вы можете легко превратить в гораздо более надежное приложение.
Краткий обзор библиотек
Это очень гибкий и невероятно легкий.
Backbone.js — это инфраструктура JavaScript, которая позволяет нам легко создавать одностраничные веб-приложения. Он очень гибкий и невероятно легкий, поэтому он стал одним из самых популярных доступных JavaScript-фреймворков.
Require.js — это загрузчик модулей (использующий шаблон проектирования AMD), который позволяет асинхронно загружать модули JavaScript и их зависимости.
Underscore.js — библиотека, предоставляющая набор служебных функций, которые можно ожидать при работе с языком программирования. Помимо прочего, он дает вам возможность перебирать коллекции, проверять, является ли код функцией и имеет ли встроенный язык шаблонов.
Что такое магистральный котел?
Backbone Boilerplate — это просто набор лучших практик и утилит для создания веб-приложений Backbone. Это не дополнительная библиотека, но она объединяет несколько библиотек для создания некоторой структуры при создании проектов Backbone.
Магистральная магистраль не является дополнительной библиотекой.
Существует несколько способов установки базовой магистрали. Самый простой (и предпочтительный) метод — плагин grunt-bbb
. Однако это требует использования Node.js и NPM, что выходит за рамки данного руководства. Вместо этого мы будем устанавливать вручную.
Для начала зайдите в репозиторий Github и загрузите копию кода (вы должны увидеть значок .zip вверху). Копия, которую вы загружаете, была изменена с оригинала с большим количеством удаленного примера кода. В примере кода есть куча очень полезных комментариев (из оригинального шаблона) — не стесняйтесь читать их в свободное время.
Это оно! Мы можем начать с создания нашего приложения.
Ваш первый модуль, книга!
Когда вы работаете с Backbone Boilerplate (или любым другим проектом, использующим AMD / Require.js), вы будете группировать функциональность по модулям и, как правило, помещать каждый модуль в отдельный файл. Это создает «разделение интересов» и позволяет вам (и всем, кто читает ваш код) легко понять, что код должен делать.
Чтобы создать свой первый модуль, просто поместите следующий код в файл app/modules/book.js
определить ([ «Пространство имен», «Использование! Хребет» ], function (namespace, Backbone) { var Book = namespace.module (); // Маршрутизатор Book.Router = Backbone.Router.extend ({ маршруты: { "книга /: р": "детали" }, детали: функция (хеш) { var view = new Book.Views.Details ({model: Library.get (hash)}); view.render (функция (эл) { . $ ( "# Главный") HTML (эл); }); } }); // Создание маршрутизатора var router = new Book.Router (); // Книжная модель Book.Model = Backbone.Model.extend ({}); // Коллекция книг Book.Collection = Backbone.Collection.extend ({ модель: Book.Model }); // Это выберет шаблон книги и отобразит его. Book.Views.Details = Backbone.View.extend ({ template: "app / templates / books / details.html", render: function (done) { var view = this; // Извлекаем шаблон, отображаем его в элементе View и вызываем. namespace.fetchTemplate (this.template, function (tmpl) { view.el.innerHTML = tmpl (view.model.toJSON ()); if (_.isFunction (done)) { сделано (view.el); } }); } }); // Это извлечет шаблон списка книг и отобразит его. Book.Views.List = Backbone.View.extend ({ template: "app / templates / books / list.html", render: function (done) { var view = this; namespace.fetchTemplate (this.template, function (tmpl) { view.el.innerHTML = tmpl ({books: view.collection.toJSON ()}); if (_.isFunction (done)) { сделано (view.el); } }); } }); // Требуется вернуть модуль на соответствие AMD возврат книги; });
Это может выглядеть много, но это действительно довольно просто. Давайте разберем это ниже:
Определение модуля AMD
определить ([ «Пространство имен», «Использование! Хребет» ], функция (пространство имен, магистраль) { var Book = namespace.module (); возврат книги; });
Это стандартный формат для любого определения модуля AMD. Вы говорите загрузчику модулей, что этому модулю нужен доступ к вашему пространству имен и магистрали, которые определены в app/config.js
. Внутри функции обратного вызова вы регистрируете свой модуль и возвращаете его в конце (что соответствует требованиям AMD).
Маршрутизатор модуля
Book.Router = Backbone.Router.extend ({}); var router = new Book.Router ();
Всякий раз, когда браузер указывает на маршрут в хэше маршрутов, вызывается связанная функция. Обычно это когда вы создаете экземпляр представления и вызываете его функцию рендеринга. Мы создаем экземпляр маршрутизатора, чтобы Backbone знал, что нужно начать выбирать связанные маршруты.
Данные модуля
Book.Model = Backbone.Model.extend ({}); Book.Collection = Backbone.Collection.extend ({ модель: Book.Model });
Здесь определяются данные вашей книги и бизнес-логика. Вы создадите новые экземпляры вашей Book.Model
для хранения каждой книги и ее атрибутов (название, автор и т. Д.). Book.Collection
связана с Book.Model
, и именно так вы представляете свои модели как сгруппированные объекты. Другими словами, в библиотеке много книг, а коллекция очень похожа на библиотеку.
Они довольно просты, но вы можете поместить любую свою бизнес-логику в объекты, которые передаются в методы расширения. Например, если вы хотите создать функцию, которая будет фильтровать книги из коллекции на основе автора, вы должны сделать что-то вроде следующего:
Book.Collection = Backbone.Collection.extend ({ модель: Book.Model, filterByAuthor: функция (автор) { вернуть this.filter (функция (книга) { возврат book.get ('author') === автор; }); } });
«Функции подчеркивания могут быть вызваны непосредственно в коллекции Backbone».
Это использует функцию filter
Underscore, которую (как и большинство функций Underscore) можно вызывать непосредственно в самой коллекции. Не стесняйтесь читать документацию Backbone для получения дополнительной информации о том, какие функции Underscore вы можете вызывать в своих коллекциях.
Та же идея относится и к вашим моделям. В идеале вы должны подталкивать всю свою бизнес-логику к модели Это может быть что-то вроде добавления возможности для пользователей настроить книгу в качестве «любимой». Сейчас вы можете удалить метод filterByAuthor
из вашей коллекции, так как мы не будем использовать его в этом руководстве.
Взгляды модуля
Book.Views.Details = Backbone.View.extend ({ template: "app / templates / books / details.html", render: function (done) { var view = this; // Извлекаем шаблон, отображаем его в элементе View и вызываем. namespace.fetchTemplate (this.template, function (tmpl) { view.el.innerHTML = tmpl (view.model.toJSON ()); if (_.isFunction (done)) { сделано (view.el); } }); } });
Ваш модуль будет содержать несколько просмотров. В нашем примере у нас есть представление списка и подробное представление. Каждый из них имеет свой собственный шаблон и функцию рендеринга, которая вызывает fetchTemplate
(определенный в namespace.js
), устанавливает результат для представлений innerHTML
и вызывает связанную функцию обратного вызова (готово). Следует отметить, что представление списка передает коллекцию в функцию шаблона, а представление сведений передает модель в функцию шаблона. В обоих случаях мы вызываем toJSON()
для параметра. Это помогает нам гарантировать, что мы просто имеем дело с данными на уровне шаблона.
Шаблоны с минимальной логикой
В app/templates/books/list.html
1
2
3
4
5
6
7
|
<h1>Listing of Books</h1>
<ul>
<% _.each(books, function(book){ %>
<li><a href=»book/<%= book.id %>»><%= book.title %></a></li>
<% });
</ul>
|
В app/templates/books/details.html
1
2
3
4
5
6
7
8
|
<h1><%= title %></h1>
<ul>
<li><b>Author: </b><%= author %></li>
<li><b>Year Published: </b><%= published %></li>
</ul>
<a href=»/»>Back to List</a>
|
Поскольку у нас есть подробное представление и представление списка, нам потребуется шаблон для каждого из них. В представлении списка мы будем перебирать нашу коллекцию и отображать ссылку на подробное представление каждой книги. В нашем подробном представлении мы показываем отдельные фрагменты данных, относящиеся к книге, по которой щелкнули. Мы можем использовать свойства напрямую, потому что мы передаем данные в функцию шаблона с их toJSON()
, которые преобразуют стандартные models/collections
в их представления JSON.
Обратите внимание на тот факт, что нам не нужно было вызывать preventDefault()
для каких-либо ссылок, которые были на странице? Это из-за кода внизу app/main.js
Мы говорим, что любая ссылка на странице без data-bypass="true"
будет автоматически вызывать preventDefault()
, используя наши маршруты Backbone вместо поведения ссылки по умолчанию.
Начальная загрузка ваших данных и настройка маршрута по умолчанию
Вверху main.js
замените код следующим:
требуется ([ «Пространство имен», // Libs "JQuery", «Использование! Хребет», // Модули «Модули / книга» ], function (пространство имен, $, Backbone, Book) { window.Library = новая книга. Коллекция ([ {id: 1, название: «Повесть о двух городах», автор: «Чарльз Диккенс», опубликовано: 1859 г.}, {id: 2, название: «Властелин колец», автор: «JRR Tolkien», опубликовано: 1954 г.}, {id: 3, название: «Хоббит», автор: «JRR Tolkien», опубликовано: 1937 г.}, {id: 4, название: «И тогда не было никого», автор: «Агата Кристи», опубликовано: 1939 г.} ]); // Определяя роутер приложения, вы можете подключить суб маршрутизаторы здесь. var Router = Backbone.Router.extend ({ маршруты: { "": "показатель" }, index: function () { var view = new Book.Views.List ({collection: Library}); view.render (функция (эл) { . $ ( "# Главный") HTML (эл); }) } }); // Все после роутера остается прежним });
Как правило, ваш серверный компонент передает данные в приложение Backbone через его API (вы настраиваете их в своих коллекциях и моделях). Однако в этом руководстве мы просто загружаем ваши представления с помощью нескольких статических книг и создаем маршрут по умолчанию, который передает библиотеку представлению списка Book
качестве его коллекции.
Единственное, что нужно изменить, это то, что вы передаете свой модуль в загрузчик модулей (обратите внимание на require
вместо define
в верхней части main.js
). Делая это, вы говорите своему приложению загрузить файл и передать его в функцию обратного вызова, чтобы иметь доступ ко всем свойствам книги.
Завершение
Есть целый ряд других вещей, чтобы действительно иметь масштабируемое веб-приложение.
Вы можете подумать, что это выглядит очень похоже на любой другой урок Backbone, который вы читали, так что же отличает его от этого? Что ж, ключом к этому является тот факт, что все функции, относящиеся к Book
, хранятся в одном модуле, который находится в своем собственном файле. Допустим, вы решили начать делиться своей коллекцией фильмов на этом сайте. Это будет так же просто, как создание app/modules/movie.js
, связанных шаблонов и main.js
для загрузки modules/movie
.
Существует целый ряд других вещей, имеющих действительно масштабируемое веб-приложение, самым большим из которых является надежный API на сервере. Однако, если вы не забудете создать разделение проблем при работе с различными модулями в вашем приложении, вам будет гораздо проще поддерживать, оптимизировать и расширять свой код, не сталкиваясь со слишком многими проблемами в результате неуправляемого кода спагетти.