Введение в Backbone.js: делаем JavaScript-приложения лучше
Backbone.js

Введение в Backbone.js: делаем JavaScript-приложения лучше

Разработка сложных пользовательских интерфейсов и SinglePage-приложений на JavaScript с использованием одного лишь jQuery может превратить код в запутанный клубок: множество callback’ов, привязка к конкретным элементам DOM и сложные манипуляции с ними — поддерживать и развивать такой код становится крайне сложно, дорого и, прямо скажем, неприятно.

Все мы проходили тот этап, когда для решения подобной проблемы мы изобретали собственные «велоcипеды». В данной статье мы познакомимся с Backbone.js, кратко рассмотрим его основные возможности, попробуем разобраться, чем же он может облегчить жизнь frontend-разработчика.

Backbone.js — это легкий MV*-фреймворк, позволяющий структурировать код JavaScript-приложений. Но прежде, чем говорить о нем, давайте разберемся с паттерном, а вернее, семейством паттернов MV* (Model-View-Whatever), наиболее известным из которых является паттерн MVC (Model-View-Controller).

Model-View-Whatever

Модель (Model) — модель содержит некое состояние приложения (JSON данные, называемые в Backbone атрибутами), а также события, позволяющие управлять изменением состояния. Модель может храниться как в памяти браузера, так и в базе данных на сервере. Упорядоченная группа моделей — это коллекция. В Backbone.js коллекция представляет собой обертку для работы с группами моделей.

Представление (View) — представление содержит логику отображения данных модели и коллекций в пользовательском интерфейсе. Представление позволяет отделить данные от их конкретного отображения в DOM-модели, что позволяет отображать одни и те же данные в разных представлениях, а также реагировать всем представлениям на изменение состояния модели.

Контроллер (Controller) — промежуточный слой между данными и представлением, контроллер передает данные в представление.

Итак, Backbone.js состоит из следующих классов:

  • Model (Модель)
  • Collection (Коллекция)
  • View (Представление)
  • Router (Роутер)

Рассмотрим подробнее каждый из них.

Модель (Model)

Модель в Backbone.js представляет собой некую сущность, содержащую данные, а также логику для работы с ними: вычисляемые свойства, валидация, права доступа.

Пример создания модели:


var Book = Backbone.Model.extend({});

Каждый экземпляр модели при создании может содержать некоторые начальные поля:


var Book = Backbone.Model.extend({
    defaults: {
        title: 'No title',
        author: 'unknown',
        releaseDate: 2011,
        description: ''
    }
});

Каждый раз при инстанцировании экземпляра модели вызывается метод initialize(). В примере ниже показано использование этого метода:


var Book = Backbone.Model.extend({
    initialize: function() {
        console.log('Book was initialized');
    },
    defaults: {
        title: 'No title',
        author: 'unknown',
        releaseDate: 2011,
        description: ''
    }
});

Создать новый экземпляр модели можно с помощью new:


// создаем экземпляр модели
var oBook = new Book({ title: 'Alice in Wonderland', author: 'Lewis Caroll' });

// считываем атрибут title
var sBookTitle = oBook.get('title');

// устанавливаем атрибут releaseDate
oBook.set({ releaseDate: '1865'  });

Изменения в примере выше сохраняются только в оперативной памяти. Если вы хотите сохранить изменения модели на сервер, используйте метод save:


oBook.save();

Так одной строчкой вы отправите запрос на сервер, если это новый объект, будет использован HTTP-метод POST, если редактируется уже существующий — метод PUT.

Коллекция (Collection)

Коллекции в Backbone.js представляют собой не что иное как группы моделей. Если проводить аналогию в базой данных, то коллекция — это результат запроса содержащий несколько записей.

Определить коллекцию можно следующим образом:


var BooksCollection = Backbone.Collection.extend({  
    model: Book
});

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


var BooksCollection = Backbone.Collection.extend( {  
    model : Book,  
    old : function() {  
        return this.filter(function(book) {   
            return book.get('releaseDate') < 1900;   
    	});  
    }
});

Просто и элегантно, не правда ли?

Инстанцировать объект коллекции можно так же, как и модель:


var oBooks = new BooksCollection();
oBooks.get(0);

В данном примере мы создали объект коллекции и получили элемент коллекции с ID равным 0.

Наконец, если вам нужно получить данные коллекции с сервера, вы можете воспользоваться методом fetch(). При этом в атрибутах коллекции должен быть указан URL, откуда мы будет получать данные.


var BooksCollection = Backbone.Collection.extend( {  
    model: Books,  
    url: '/books' 
} );  
  
var oBooks = new BooksCollection();  
oBooks.fetch();

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

Представления в Backbone.js выполняют две основные функции:

  • Отображение состояния приложения и данных модели пользователям;
  • Реагирование на события от элементов DOM и моделей/коллекций

Cоздадим простое представление:


var BookView = Backbone.View.extend({
    tagName: ‘div’,
    className: ‘book-item’,
    render: function() {
        this.$el.html(this.model.get(‘title’));
        return this;
    }
});

Атрибут $el ссылается на обертку, которую создает представление. В нашем примере, мы создали элемент <div> с классом ‘book-item’ и поместили в него заголовок книги.

В этом примере мы не использовали возможность шаблонизации, если представление более сложное, можно использовать шаблонизатор из библиотеки Underscore.js.

Давайте изменим наш пример с использованием шаблонизатора:


var BookView = Backbone.View.extend({
    tagName: 'div',
    className: 'book-item',
    template: _.template($('#bookTemplate').html()),
	
    render: function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    }
});

Сам шаблон можно поместить непосредственно на HTML-странице:


<script id='bookTemplate' type='text/template'>
    <h3 class="title"><%= title %></h3>
    <div class="description">
	<p class="release-date"><%= previewText %></p>
	<p><%= previewText %></p>					
    </div>
</script>

Также представления в Backbone.js могут слушать события от элементов DOM и от моделей и коллекций.


events: {
    'click .title': 'onTitleClick'
},

'onTitleClick': function(event) {
    alert('Клик');
}

В данном примере мы в качестве обработчика щелчка мыши по элементу с классом title назначили функцию ’onTitleClick’ и определили эту функцию. Так представления могут реагировать на события пользовательского интерфейса и менять, соответственно, состояние модели и наоборот, отслеживать состояние модели и изменять отображение.

Роутер (Router)

Роутер используется для маршрутизации внутри приложения.


var appRouter = Backbone.Router.extend({
    routes: {
        "": "start",
        "!/": "start",
        "!/books": "books",
    },

    start: function() { 
        // код, который должен выполняться на главной странице приложения
    },

    books: function() { 
        // код, который должен выполняться, когда URL страницы
        // http://somedomain.com/#!/books
    },
});

После того, как созданы все роутеры, в момент инициализации приложения необходимо вызвать функцию Backbone.history.start();

Заключение

В данной статье мы лишь поверхностно рассмотрели возможности библиотеки Backbone.js, которые могут быть использованы для создания структурированных JavaScript-приложений. В дальнейшем мы более подробнее рассмотрим систему событий, а также возможности шаблонизации.

Рассылка
Подпишитесь на рассылку и получайте дайджест новостей и статей.
Никакого спама!
Подписаться