Ускоренное изучение Backbone. Часть 1

Опубликовано: 14 октября 2014 г.
  • SPA
Backbone - небольшая библиотека на javascript, которая структурирует клиентский код. Чаще всего, Backbone используется для создания одностраничных приложений.

Backbone.js имеет жесткую зависимость от библиотеки underscore.js и слабую от JQuery. Он состоит из следующих модулей:

  • Views (Представления)
  • Events (События)
  • Models (Модели)
  • Collections (Коллекции)
  • Routers (Маршрутизаторы)
Backbone

Мы разберем все эти модули на простых примерах и первое, с чего мы начнем, - это приложение, которое выводит Привет, мир.

Для начала работы скачайте этот простой HTML файл. Этот файл содержит ссылки на библиотеки, которые нам понадобятся (JQuery, Underscore.js, Backbone.js и Backbone-localStorage.js) и обозначенные места для вашего HTML и JS кода. Не беспокойтесь о библиотеках, мы обязательно объясним для чего они нужны.

После загрузки вышеупомянутого файла, обратите внимание на HTML, где вся ваша страница будет построена с использованием класса Backbone.Views!

Ваше JS приложение будет загружено вот сюда:

<div id="container">Загрузка...</div>

Views (Представления)

Backbone-представления являются эквивалентом «контроллеров» MVC-фреймворков (например, Ruby On Rails). Представления в Backbone.js отвечают за отображение данных приложения, а также могут реагировать на события, которые возникают в моделях, коллекциях или реагировать на события DOM-элементов.

Для создания представления нужно всего-навсего расширить класс Backbone.View. Изучите представленный ниже код с комментариями, а затем вставьте его в яваскрипт-блок загруженного HTML файла.

var AppView = Backbone.View.extend({
   // el - ссылка на DOM-элемент, в который представление 
   // вставляет сформированное содержимое
   el: '#container',
   // Функция initialize вызывается при создании 
   // экземпляра представления
   initialize: function(){
      this.render();
   },
   // Для вызова jQuery функций представление Backbone 
   // имеет свойство $el
   render: function(){
      this.$el.html("Привет, мир");
   }
});

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

var appView = new AppView();

Отлично, мы получили надпись 'Привет, мир' и познакомились с Представлениями (см. полный код здесь)

Backbone и шаблоны

Поскольку Backbone тесно работает с библиотекой под названием underscore.js (или просто _.js), вы можете воспользоваться доступным в ней шаблонизатором. Также, вы можете воспользоваться любым другим шаблонизатором, который вам нравится, например mustache, или handlebars. Давайте для простоты придерживаться _.js.

Шаблоны в Underscore имеют следующий синтаксис:

_.template(templateString, [data], [settings])

Здесь templateString - настройки шаблонизатора. Вы можете использовать в нем заглушку вида <%= %> и <%- %> для динамически вставляемых данных. Последняя экранирует спец. символы, делая HTML код безопасным, в то время как первая - нет. Кроме того, вы можете использовать <% %> для запуска любого javascript кода.

[data] - объект с данными, необязательный патаметр.

С помощью необязательного параметра [settings] мы можем переопределить любые настройки шаблонизатора, заданые в templateString

Давайте посмотрим его в действии и перепишем наш 'Привет, мир' используя шаблонизатор в Underscore.

var AppView = Backbone.View.extend({
   el: $('#container'),
   // Шаблон, который имеет заглушку 'who', которая
   // потом заменится неким значением
   template: _.template("<h3>Привет, <%= who %></h3>"),
   initialize: function(){
      this.render();
   },
   render: function(){
      // Рендерим, подставляя в заглушку 'who'
      // значение, равное 'мир'
      this.$el.html(this.template({who: 'мир'}));
    }
});

var appView = new AppView();

Запустите приложение снова и убедитесь, что оно работает с шаблоном.

Начнем снова с HTML болванкой, использованной ранее. Теперь, вместо div#container давайте добавим следующий код:

<section id="todoapp">
   <header id="header">
      <h1>Todos</h1>
      <input id="new-todo" placeholder="Что должно быть сделано?">
   </header>
   <section id="main">
      <ul id="todo-list"></ul>
   </section>
</section>

Мы собираемся реализовать неупорядоченный список ul элементов с чекбоксами.

Models (Модели)

Модели - сердце каждого приложения. Они содержит интерактивные данные и логику, с ними связанную, такую как получение, установка и проверка данных, значения по умолчанию, инициализации данных, преобразования и д.р. Для нашего примера, мы собираемся создать модель под названием Todo, которая будет хранить строку текста (title) и была ли задача была завершена, или нет (completed).

// создаем пространство имен для нашего приложения
var app = {};

app.Todo = Backbone.Model.extend({
   defaults: {
      title: '',
      completed: false
   }
});

Заметьте, что для удобства сделано так, что названия классов выделены заглавной буквой, а переменные и объекты - нет. Еще один важный аспект моделей - это то, что их свойства являются динамическими; они могут быть созданы на лету и не иметь никаких особенностей.

Протестируем наш код. Для этого откройте консоль браузера (в Хроме: ctrl+shift+i, или ⌘+alt+i) и попробуйте ввести следующий код, чтобы ознакомиться с моделями:

var todo = new app.Todo({title: 'Изучаем Backbone.js', completed: false}); // создаем объект с атрибутами
todo.get('title'); // "Изучаем Backbone.js" 
todo.get('completed'); // false
todo.get('created_at'); // undefined
todo.set('created_at', Date());
todo.get('created_at'); // "Wed Sep 12 2012 12:51:17 GMT-0400 (EDT)"

Коллекции в Backbone (Backbone.Collection)

Коллекции - это упорядоченные множества моделей, где вы можете получить и установить модели в коллекции, прослушивать события, когда любой элемент в коллекции изменяется и извлекать данные модели с сервера. Например: todoList.fetch();.

Коллекции позволяют сохранять данные (в базе данных, файлах, памяти) и это требует ссылку на нее. Поэтому, необходимо указать параметр url с относительнным URL, где ресурс модели будет расположен на сервере. В противном случае, вы получите такую ошибку: A "url" property or function must be specified (Свойство "url", или функция должна быть указана).

Для упрощения, мы не будем импользовать сервер (я сделаю отдельный урок для этого); вместо этого мы будем использовать локальное хранилище (local storage) HTML5 для persistence через Backbone плагин. Таким образом, мы должны определить свойство LocalStorage вместо URL. Необходимо подключить backbone-localstorage.js с остальными вашими библиотеками как в примере.

app.TodoList = Backbone.Collection.extend({
   model: app.Todo,
   localStorage: new Store("backbone-todo")
});

// экземпляр коллекции
app.todoList = new app.TodoList();

Протестируем наш код. Для этого снова откройте консоль браузера и попробуйте ввести следующий код:

var todoList = new app.TodoList()
todoList.create({title: 'Изучаем коллекции'}); // заметьте что 'completed' будет установлено в false по умолчанию
var lmodel = new app.Todo({title: 'Learn Models', completed: true});
todoList.add(lmodel);
todoList.pluck('title');     // ["Изучаем коллекции", "Изучаем Модели"]
todoList.pluck('completed'); // [false, true]
JSON.stringify(todoList);    // "[{"title":"Изучаем коллекции","completed":false,"id":"d9763e99-2267-75f5-62c3-9d7e40742aa6"},{"title":"Изучаем Модели","completed":true}]"

Backbone.View

Как уже упоминалось выше, Представления в Backbone не имеют HTML-меток для нашего приложения, зато они (как контроллеры в MVC-фреймворке) обрабатывают данные и связывают их с шаблонами и рендерят HTML-код, основываясь на событиях и изменении данных.

Представления имеют 4 основных свойства: el, initialize, render и events. Мы уже видели в деле первые три, а совсем скоро познакомимся с четвертым. Вы ведь не забыли еще наш "Привет, мир":

var AppView = Backbone.View.extend({
   el: '#container',
   initialize: function(){
      this.render();
   },
   render: function(){
      this.$el.html("Привет, мир");
   }
});

Каждое представление должно ссылаться на DOM-элемент и el - это и есть та самая ссылка. this.el создается из таких свойств Представления, как el, tagName, className, id, или attributes. Если ни один из них не указан, то this.el является пустым div. view.$el - это закешированный jQuery объект элемента представления (view.el).

С помощью функции initialize у вас есть возможность передать параметры, которые будут прикреплены к модели, коллекции, или view.el.

Функция render вставляет отметки в элементы. Не все Представления требуют наличие функции render, как вы можете увидеть в примере, они просто вызывают другие рендерные функции.

События (events) записываются в следующем формате:

{"<EVENT_TYPE> <ELEMENT_ID>": "<CALLBACK_FUNTION>"}

Например:

events: {'keypress #new-todo': 'createTodoOnEnter'}

В jQuery мы бы написали:

$('#new-todo').keypress(createTodoOnEnter);

Теперь вернемся к нашему To-Do приложению: Нам нужно Представление, которое отрендерит каждый объект из модели Todo на страницу. Шаблон item-template и Представление app.TodoView сделают то, что нам нужно.

<script type="text/template" id="item-template">
   <div class="view">
      <input class="toggle" type="checkbox">
      <label><%- title %></label>
   </div>
</script>

В следующем блоке кода мы описываем Представление, используя заданный выше шаблон (#item-template) чтобы вывести заголовок из model.

// рендерим индивидуальный todo-элемент списка (li)
    app.TodoView = Backbone.View.extend({
      tagName: 'li',
      template: _.template($('#item-template').html()),
      render: function(){
        this.$el.html(this.template(this.model.toJSON()));
        return this; // включить цепочку вызовов
      }
    });

Когда мы создаем Представления, они могут получить любой параметр, который нам нужен. В нашем случае мы называем его model, так как то, что нам нужно создается с помощью модели (т.е. todo):

var view = new app.TodoView({model: todo});

Также обратите внимание, что он использует tagName: li вместо el. Это означает, что новые отрендеренные элементы будут помещены в <li></li>

Backbone.Events

Этот модуль может быть смешан с каким-либо объектом, чтобы придать ему поведение издатель-подписчик. События предоставляют несколько методов, из которых мы будем обсуждать следующие: on, off и trigger. Если это вы знакомы с JQuery, то имеете представление как они работают.

Метод on привязывает функцию обратного вызова к объекту. Формат записи:

object.on(event, callback, [context])

Здесь event - событие, callback - вызываемая функция, context - контекст вызова (необязательный параметр)

Также вы можете использовать bind. Эта функция связывает объект с событием и функцией обратного вызова. Когда запускается событие, она запускает функцию обратного вызова. Например:

todoList.on('add', this.addAll, this);

Каждый раз, когда добавляется новая единица в Backbone.Collection, запускается событие add. В вышеуказанном примере после запуска события, запускается функция обратного вызова addAll() и текущий объект передается с this в качестве контекста.

События можно также установить на произвольные объекты, используя underscore.js с помощью функции extend:

var object = {},
    callback = function(msg) { 
         console.log("Сработало " + msg); 
    };

_.extend(object, Backbone.Events);

object.on("my_event", callback);

object.trigger("my_event", "Мое пользовательское событие");

Теперь нам нужно другое Представление, чтобы взять коллекцию и отрендерить каждый пункт задачи. Мы будем называть его 'AppView'. Взгляните на этот код и попытайтесь идетитфицировать каждый из элементов (мы уже описали их в предыдущих разделах):

// рендер полного списка, вызывающего TodoView для каждого события
   app.AppView = Backbone.View.extend({
      el: '#todoapp',
      initialize: function () {
        this.input = this.$('#new-todo');
        // когда новые элементы добавляются в коллекцию, 
        // мы рендерим их с помощью addOne
        app.todoList.on('add', this.addOne, this);
        app.todoList.on('reset', this.addAll, this);
        app.todoList.fetch(); // Загружаем список из local storage
      },
      events: {
        'keypress #new-todo': 'createTodoOnEnter'
      },
      createTodoOnEnter: function(e){// Код клавиши ENTER = 13
        if ( e.which !== 13 || !this.input.val().trim() ) { 
          return;
        }
        app.todoList.create(this.newAttributes());
        this.input.val(''); // Очищаем input
      },
      addOne: function(todo){
        var view = new app.TodoView({model: todo});
        $('#todo-list').append(view.render().el);
      },
      addAll: function(){
        this.$('#todo-list').html(''); // Очищаем список
        app.todoList.each(this.addOne, this);
      },
      newAttributes: function(){
        return {
          title: this.input.val().trim(),
          completed: false
        }
      }
   });

   //--------------
   // Инициализация
   //--------------   

   app.appView = new app.AppView();

В заключительной части нашего урока по Ускоренному изучению Backbone мы узнаем, как реализовать создание, чтение, обновление и удаление для моделей!

Популярные статьи
2D игра на Unity. Подробное руководство. Часть 1
  • unity
2D игра на Unity. Подробное руководство. Часть 1
Адаптивный слайдер без Javascript на CSS3
  • слайдер
Адаптивный слайдер без Javascript на CSS3
Работа с Unity в 2D
  • unity
Работа с Unity в 2D
2D игра на Unity. Подробное руководство. Часть 3
  • unity
2D игра на Unity. Подробное руководство. Часть 3
2D игра на Unity. Подробное руководство. Часть 4
  • unity
2D игра на Unity. Подробное руководство. Часть 4
2D игра на Unity. Подробное руководство. Часть 5
  • unity
2D игра на Unity. Подробное руководство. Часть 5
2D игра на Unity. Подробное руководство. Часть 6
  • unity
2D игра на Unity. Подробное руководство. Часть 6
Учебник по новому GUI в Unity. Часть 2.
  • unity
Учебник по новому GUI в Unity. Часть 2.
Учебник по новому GUI в Unity. Часть 1.
  • unity
Учебник по новому GUI в Unity. Часть 1.

HTML LESS LESS React
Онлайн журнал для профессиональных веб-дизайнеров и программистов
БлогПлагиныГрафикаИнструменты
CanvasSPAcssjavascriptjqueryphotoshopphpunitywordpress{"fieldValue":[{"image_preview":"","image_demo":"","example":""}],"fieldSettings":{"autoincrement":1}}{"fieldValue":[{"image_preview":"https://cdn-images-1.medium.com/max/800/1*OIBUnA4NokXK14IMR5csTw.jpeg","image_demo":"https://cdn-images-1.medium.com/max/800/1*OIBUnA4NokXK14IMR5csTw.jpeg","example":""}],"fieldSettings":{"autoincrement":1}}Аудио/Видеоаккордеонанимациябазы данныхбраузерные игрыверсткагалереяграфикакартыкнопкименюпараллаксподсказкипопаппрелоадерслайдертаймерформычекбоксыэлементы интерфейса
© 2009-2017 WebSketches.ru