Используйте Backbone.js для ускорения взаимодействия

Автор: Monica Porter
Дата создания: 13 Март 2021
Дата обновления: 15 Май 2024
Anonim
Павел Юрийчук "Опыт разраб. моб. веб приложения с использованием Backbone.js, Require.js, Zepto.js"
Видео: Павел Юрийчук "Опыт разраб. моб. веб приложения с использованием Backbone.js, Require.js, Zepto.js"

Содержание

Если вы хотите быстро создать небольшой инструмент JavaScript, вы, вероятно, не думаете об использовании фреймворка. Легче собрать код jQuery, чем устанавливать и изучать новый фреймворк, верно? Неправильно, Backbone.js - это сверхлегкий клеевой фреймворк, который выглядит так же, как обычный старый JavaScript, который вы писали.

Мы создаем множество статических прототипов здесь, в ZURB, потому что нам нравится иметь возможность пролистывать страницы без необходимости писать какой-либо внутренний код. Часто мы добавляли тускло-серые изображения-заполнители, или иногда мы искали на Flickr образцы изображений, чтобы помочь нам визуализировать, что может быть в окончательном варианте. Так было до одной волшебной пятницы, когда мы решили, что было бы здорово написать немного JavaScript для решения наших проблем. Мы хотели иметь возможность искать и выбирать фотографии на Flickr прямо из самих изображений-заполнителей. Мы бы назвали его FlickrBomb, и это рассказ о том, как мы создали его с помощью Backbone.js.


Перед чтением настоятельно рекомендуется быстро взглянуть на FlickrBomb. Это одна из тех сделок, «один клик стоит тысячи слов». Давай, подождем.

В наши дни существует множество фреймворков JavaScript, SproutCore, JavaScriptMVC, Spine, Sammy, Knockout. Но нам понравился Backbone.js в этом конкретном проекте по нескольким причинам:

1. Он легкий (на самом деле на 100% обезжиренный).

  • по весу, при этом последняя упакованная версия составляет около 4,6 КБ
  • в коде, поскольку это чуть более 1000 строк кода, нетрудно проследить трассировку стека до внутренних компонентов, не теряя рассудка.

2. Похоже на JavaScript.

  • потому что это JavaScript, вот и все
  • он использует jQuery, который в наши дни знает даже ваша бабушка

3. Супер простая настойчивость


  • из коробки он сохраняет данные на бэкэнд (через REST), но, добавив один плагин, он вместо этого сохранит данные в локальном хранилище.
  • поскольку он абстрагирует API сохранения, мы могли бы сохранить его в бэкэнде REST, просто удалив плагин локального хранилища.

Тогда приступим

Поскольку Backbone.js - это просто JavaScript, все, что нам нужно сделать, это включить его вместе с Underscore.js на страницу. jQuery не является жесткой зависимостью для Backbone как таковой, но мы собираемся его использовать, поэтому включим его здесь. Мы также подключим подключаемый модуль локального хранилища, поскольку нам не нужно беспокоиться о настройке серверной части. Обратите внимание, что здесь для простоты напрямую связывались файлы, но вы всегда должны размещать свои собственные ресурсы в производственной среде.

script src = "http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"> / script> script src = "http://documentcloud.github.com/backbone/ backbone-min.js "> / script> script src =" http://documentcloud.github.com/underscore/underscore-min.js "> / script> script src =" https://raw.github.com/ jeromegn / Backbone.localStorage / master / backbone.localStorage-min.js "> / скрипт>

Весь следующий код в этой статье относится к нашему приложению, поэтому мы можем включить его в файл app.js или просто встроить, если вам это нравится. Только не забудьте включить его после Backbone. Backbone позволяет абстрагироваться от частей нашего приложения, чтобы сделать их модульными для упрощения повторного использования и более удобочитаемыми для других. Чтобы лучше проиллюстрировать эту абстракцию, мы собирались объяснить дизайн FlickrBomb снизу вверх, начиная с моделей и заканчивая видами.


Наша первая модель

Первое, что нам нужно было решить, - это вытащить фотографии с Flickr. Моделировать FlickrImage в backbone достаточно просто, мы создадим новую модель под названием FlickrImage и добавим несколько методов, которые помогут нам получить большие пальцы разного размера.

var FlickrImage = Backbone.Model.extend ({fullsize_url: function () {return this.image_url ('medium');}, thumb_url: function () {return this.image_url ('square');}, image_url: function ( size) {var size_code; switch (size) {case 'square': size_code = '_s'; break; // 75x75 case 'medium': size_code = '_z'; break; // 640 на самой длинной стороне case 'large ': size_code =' _b '; break; // 1024 на самой длинной стороне default: size_code =' ';} return "http: // farm" + this.get (' farm ') + ".static.flickr.com / "+ this.get ('server') +" / "+ this.get ('id') +" _ "+ this.get ('secret') + size_code +" .webp ";}})

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

Когда мы извлечем фотографии с Flickr, мы получим достаточно информации для создания URL-адресов для всех размеров. Однако эта сборка оставлена ​​нам, поэтому мы реализовали функцию .image_url (), которая принимает параметр размера и возвращает общедоступную ссылку. Поскольку это базовая модель, мы можем использовать this.get () для доступа к атрибутам модели. Таким образом, с помощью этой модели мы можем сделать следующее в другом месте кода, чтобы получить URL-адрес изображения Flickr.

flickrImage.image_url (’large’)

Довольно лаконично, а? Поскольку эта модель специфична для нашего приложения, мы добавим несколько функций-оберток для полноразмерных изображений и изображений большого пальца.

Коллекция изображений

FlickrBomb работает с коллекциями изображений, а не с отдельными изображениями, и Backbone имеет удобный способ моделирования этого. Метко названная Коллекция - это то, что мы будем использовать для группировки изображений Flickr вместе для одного заполнителя.

var FlickrImages = Backbone.Collection.extend ({модель: FlickrImage, ключ: flickrbombAPIkey, страница: 1, выборка: функция (ключевые слова, успех) {var self = this; success = success || $ .noop; this.keywords = ключевые слова || this.keywords; $ .ajax ({url: 'http://api.flickr.com/services/rest/', данные: {api_key: self.key, формат: 'json', метод: 'flickr. photos.search ', tags: this.keywords, per_page: 9, page: this.page, лицензия: flickrbombLicenseTypes}, dataType:' jsonp ', jsonp:' jsoncallback ', success: function (response) {self.add (response) .photos.photo); success ();}});}, nextPage: function (callback) {this.page + = 1; this.remove (this.models); this.fetch (null, callback);}, prevPage: function (callback) {if (this.page> 1) {this.page - = 1;} this.remove (this.models); this.fetch (null, callback);}});

Здесь нужно отметить пару моментов. Во-первых, модель Атрибут сообщает коллекциям, какой тип модели он собирает. У нас также есть некоторые атрибуты, которые мы инициализировали для использования в дальнейшем: key - это наш ключ Flickr API, вы захотите заменить flickrbombAPIkey строкой вашего собственного ключа Flickr API. Получить ключ Flickr API легко и бесплатно, просто перейдите по этой ссылке: www.flickr.com/services/api/misc.api_keys.html. Атрибут страницы - это текущая страница фотографий Flickr, на которых мы находимся.

Большой метод здесь - это .fetch (), который абстрагирует детали извлечения фотографий из Flickr API. Чтобы избежать проблем с междоменными запросами, мы используем JSONP, который поддерживают как Flickr API, так и jQuery. Другие параметры, которые мы передаем в API, не требуют пояснений. Особый интерес представляют вызываемые здесь функции Backbone. В обратном вызове успеха мы используем .add (), функцию, которая принимает массив атрибутов модели, создает экземпляры модели из этих атрибутов, а затем добавляет их в коллекцию.

Функции .nextPage () и .prevPage () сначала изменяют страницу, которую мы хотим отобразить,
используйте функцию сбора .remove (), чтобы удалить все существующие модели из
коллекции, а затем вызовите fetch, чтобы получить фотографии для текущей страницы (которую мы просто
измененный).

Изображение FlickrBombImage

Возвращаясь к прошлому, нам нужна еще одна модель для представления изображения-заполнителя, которое будет состоять из коллекции FlickrImages и текущего выбранного FlickrImage. Мы назовем эту модель FlickrBombImage.

var localStorage = (supports_local_storage ())? новый магазин ("flickrBombImages"): null; var FlickrBombImage = Backbone.Model.extend ({localStorage: localStorage, инициализация: функция () {_.bindAll (this, 'loadFirstImage'); this.flickrImages = new FlickrImages (); this.flickrImages.fetch (this.get ('ключевые слова'), this.loadFirstImage); this.set (id: this.get ("id")); this.bind ('change: src', this.changeSrc) ;}, changeSrc: function () {this.save ();}, loadFirstImage: function () {if (this.get ('src') === undefined) {this.set ({src: this.flickrImages. first (). image_url ()});}}});

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

Backbone позволяет нам определить функцию .initialize (), которая будет вызываться при создании экземпляра модели. Мы используем эту функцию в FlickrBombImage, чтобы создать новый экземпляр коллекции FlickrImages, передать ключевые слова, которые будут использоваться для этого изображения, а затем получить изображения из Flickr.

Функция .loadFirstImage () была передана в качестве обратного вызова для запуска, когда изображения были загружены из Flickr. Как вы, наверное, догадались, эта функция устанавливает текущее изображение как первое в коллекции с Flickr. Этого не происходит, если текущее изображение уже установлено.

Мы также собираемся использовать обратные вызовы атрибутов Backbone для запуска нашей функции .changeSrc () при изменении атрибута src этой модели. Все, что делает этот обратный вызов, - это вызов .save (), функции модели Backbone, которая сохраняет атрибуты модели для любого уровня хранилища, который был реализован (в нашем случае localstore). Таким образом, всякий раз, когда выбранное изображение изменяется, оно немедленно сохраняется.

Слой просмотра

Теперь, когда у нас есть весь бэкэнд (ну, фронтенд бэкэнд) код, мы можем собрать представления. Представления в Backbone немного отличаются от представлений в других традиционных фреймворках MVC. В то время как представление обычно касается только представления, Backbone View также отвечает за поведение. Это означает, что ваше представление не только определяет, как что-то выглядит, но и что оно должно делать при взаимодействии.

Представление обычно (но не всегда) привязано к некоторым данным и проходит три фазы для создания разметки представления из этих данных:

1. Инициализируется объект View и создается пустой элемент.
2. Вызывается функция рендеринга, которая генерирует разметку для представления, вставляя ее в элемент, созданный на предыдущем шаге.
3. Элемент прикреплен к DOM.

Может показаться, что создание некоторой разметки требует больших усилий, и мы еще даже не касаемся поведенческой части представления, но это важно, и вот почему. Каждый раз, когда вы изменяете элементы, которые находятся в DOM, вы запускаете что-то, что называется перекомпоновкой браузера. Перекомпоновка - это браузер, который пересчитывает расположение всех элементов на странице. Перекомпоновка браузера может плохо сказаться на производительности, если вызывается в событии перетаскивания или изменения размера, которое запускается с очень коротким интервалом, но, что еще хуже, они выглядят небрежно. С помощью сложных манипуляций со страницей вы действительно можете видеть, как элементы добавляются на страницу, и изменяющееся положение элементов. Следуя шаблону инициализации, рендеринга и присоединения Backbone, вы гарантируете однократное переформатирование, и изменения на странице будут восприниматься мгновенно, независимо от сложности манипуляций с элементами.

FlickrBombImageView

var FlickrBombImageView = Backbone.View.extend ({tagName: "div", className: "flickrbombContainer", lock: false, template: _.template ('div id = "% = this.image.id.replace (" ", "")%> "... / div> '), initialize: function (options) {_.bindAll (this,' addImage ',' updateSrc ',' setDimentions ',' updateDimentions '); var keywords = options. img.attr ('src') .replace ('flickr: //', ''); this. $ el = $ (this.el); this.image = new FlickrBombImage ({ключевые слова: ключевые слова, id: параметры. img.attr ('id')}); this.image.flickrImages.bind ('add', this.addImage); this.image.bind ('change: src', this.updateSrc);}, события: { "click .setupIcon": "clickSetup", "click .flickrbombFlyout a.photo": "selectImage", "click .flickrbombFlyout a.next": "nextFlickrPhotos", "click .flickrbombFlyout a.prev": "prevFlickrPhotos"}, render: function () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); вернуть это;}, ...});

Функции этого представления опущены для краткости, исходный код полностью доступен на GitHub: github.com/zurb/flickrbomb

В верхней части представления у нас есть пара атрибутов, специфичных для Backbone. tagName и className используются для определения тега и класса, которые будут применены к этому элементу представления. Помните, что первый шаг создания представления - это создание объекта, и поскольку это создание выполняется Backbone, нам необходимо указать элемент и класс. Обратите внимание, что Backbone имеет разумные значения по умолчанию; если мы опустим эти атрибуты, по умолчанию используется div, и никакой класс не будет применяться, если вы его не укажете.

Атрибут шаблона является условным, но не обязательным. Мы используем его здесь, чтобы указать функцию шаблона JavaScript, которую мы будем использовать для создания нашей разметки для этого представления. Мы используем функцию _.template (), включенную в Underscore.js, но вы можете использовать любой шаблонизатор, который вам больше нравится, мы не будем вас осуждать.

В нашей функции .initialize () мы извлекаем строку ключевых слов из тега изображения, а затем создаем модель FlickrBombImage, используя эти ключевые слова. Мы также привязываем функцию .addImage () к запуску при добавлении FlickrImage в коллекцию FlickrImages. Эта функция добавит только что добавленный FlickrImage во всплывающее меню выбора изображений. Последняя и самая важная строка привязывает функцию .updateSrc () к срабатыванию при изменении текущего выбранного FlickrImage. Когда текущее изображение изменяется в модели, эта функция запускается, обновляет атрибут src элемента изображения, а CSS изменяет размер и обрезает изображение, чтобы оно соответствовало размерам изображения, указанным пользователем.

события: {"click .setupIcon": "clickSetup", "click .flickrbombFlyout a.photo": "selectImage", "click .flickrbombFlyout a.next": "nextFlickrPhotos", "click .flickrbombFlyout a.prev": "prevFlickrPhotos "}

После .initialize () у нас есть поведенческая часть представления. Backbone предоставляет удобный способ привязки событий с помощью объекта событий. Объект событий использует метод jQuery .delegate () для фактической привязки к элементу View, так что независимо от того, какие манипуляции вы выполняете с элементом внутри представления, все ваши связанные события по-прежнему будут работать. Он работает так же, как jQuery .live (), за исключением того, что вместо привязки событий ко всему документу вы можете привязать их в рамках любого элемента. Ключ каждой записи в объекте событий состоит из события и селектора, значение указывает на ту функцию, которая должна быть привязана к этому событию. Обратите внимание, что .delegate () не работает с некоторыми событиями, такими как submit, см. Документацию jQuery .live () для получения полного списка поддерживаемых событий.

визуализация: функция () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); вернуть это;}

Наконец, у нас есть функция .render (), которая отвечает за создание нашей разметки и выполнение любой дополнительной работы, которая не может быть выполнена до тех пор, пока разметка View не будет добавлена ​​в элемент View. После рендеринга нашего шаблона нам нужно вызвать .fetch () для нашего FlickrBombImage. .fetch () - это функция Backbone, которая получает последнюю копию модели из уровня сохраняемости. Если бы мы сохранили эту модель раньше, .fetch () извлек бы эти данные сейчас. После того, как изображение было получено, нам нужно вызвать resize, чтобы правильно расположить его.

Домашняя растяжка

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

$ ("img [src ^ = 'flickr: //']") .each (function () {var img = $ (this), flickrBombImageView = new FlickrBombImageView ({img: img}); img.replaceWith (flickrBombImageView. render (). el);});

Этот небольшой фрагмент нужно запустить внизу страницы или в обратном вызове готового документа, чтобы гарантировать, что он сможет найти изображения-заполнители, которые он заменит. Мы используем соглашение об указании flickr: // [KEYWORD] в атрибуте src тега изображения, чтобы указать, что он должен быть заполнен изображениями из Flickr. Мы находим элементы изображения с соответствующим атрибутом src, создаем новый FlickrBombImageView, а затем заменяем изображение нашим. Мы берем копию исходного изображения и передаем ее нашему FlickrBombView, чтобы мы могли извлечь некоторые дополнительные параметры конфигурации, которые могли быть указаны в элементе.

Конечным результатом всей этой тяжелой работы стал очень простой API для людей, использующих библиотеку. Они могут просто определять теги изображений, используя соглашение flickr: //, оставлять код FlickrBomb внизу своей страницы и бац, они получили изображения-заполнители с Flickr.

Также отлично работает с большими веб-приложениями

У нас есть большое веб-приложение под названием Notable, которое было написано без заботы о создании контента на стороне клиента. Когда мы хотели сделать разделы приложения турбонаддувом, генерируя контент на стороне клиента, мы выбрали Backbone. Причины были те же: мы хотели облегчить структуру кода, чтобы упорядочить код, но не заставлять нас переосмысливать все приложение.

Мы с большим успехом запустили изменения в начале этого года и с тех пор воспеваем Backbones.

Дополнительные ресурсы

Backbone - это гораздо больше, чем то, что я рассмотрел в этой статье, часть C (контроллер) MVC (контроллер представления модели) для начинающих, которая на самом деле является R (маршрутизатором) в последней версии. И все это описано в документации по Backbone, светлой субботним утром гласил:
documentcloud.github.com/backbone/

Если вам нравятся более традиционные учебники, то ознакомьтесь с хорошо документированным кодом этого приложения todo, написанного на Backbone:
documentcloud.github.com/backbone/docs/todos.html

Увлекательные статьи
Лучший веб-хостинг: лучшие веб-сервисы в 2021 году
Далее

Лучший веб-хостинг: лучшие веб-сервисы в 2021 году

Топ 5 услуг веб-хостинга01. Blueho t 02. Ho tinger 03. Ho tGator 04. InMotion 05. itegroundПодписка на лучшие услуги веб-хостинга позволит вашему веб-сайту быстро подключиться к сети и обеспечить его...
13 потрясающих галерей веб-сайтов, которые вдохновят ваш дизайн
Далее

13 потрясающих галерей веб-сайтов, которые вдохновят ваш дизайн

Галереи веб-сайтов, также известные как галереи C : они являются отличным источником идей, а также держат нас в курсе последних тенденций веб-дизайна. У всех нас есть галерея веб-дизайна, где можно бы...
Лучшие предложения Apple Watch SE: самые низкие цены будут доступны в мае 2021 года.
Далее

Лучшие предложения Apple Watch SE: самые низкие цены будут доступны в мае 2021 года.

Apple Watch E были выпущены только в сентябре 2020 года, но уже было заключено множество отличных предложений на то, что, по нашему мнению, является идеальным вариантом Apple Watch для творческих люде...