2. Типичный application.js:
1. Код не имеет структуры - набор обработчиков
событий
2. Код растет - тяжело ориентироваться
3. Совсем не просто проследить логику
взаимодействия объектов на странице
вторник, 15 ноября 11 г.
3. Рефакторинг - использование волшебных (function(){})()
var MyCoolModule = (function(opts){ 1. Код чуть более структурирован - функционал
//public variable
организован в модули
this.settings = opts;
//private var
var bla = 0;
//public method 2. Код отдельного модуля продолжает оставаться
this.reset = function (){} довольно тяжелым и неструктурированным -
генерация html, обмен данными смешано
//private method
function init(){};
//initializer
self.init(); 3. Если страница довольна интерактивна и объемна -
})(); для оптимизации скорости и потребления памяти сырые
данные хранятся в данных js - скорее всего в объекте(ах)
Используем: глобального пространства имен.
var myCoolObject = new MyCoolModule({params});
//call of public functions
myCoolObject.reset();
4. Скорее всего в этот момент мы уже воспринимаем нашу
страницу как набор объектов(визуальных,объектов по типу
данных) - но js код остается в виде методов класса, т.е.
соответствующих объектов(инкапсулирующих данные,
представляющие АПИ) - нет. Как следствие -
дополнительные расходы на работу с html кодом,
идентификацию классов источника события и пр.
вторник, 15 ноября 11 г.
4. Рефакторинг - MVC
1. Bacbone.js - легковесен, дает только шаблон, обеспечивая
свободу, не требует специального html кода
2. Knockout.js - Model-View-ViewModel (MVVM), работает с
помощью data аттрибутов, что означает специальный html код
3. Sproutcore - мощный и тяжеловесный, включает MVC
фреймворк и визуальные компоненты
4. Require JS - по сути больше п.6, но использует AMD
(Asynchronous Module Definition) - загрузку js по требованию и
ассинхронно
5. etc
6. Custom implementations - можно написать и самому :)
вторник, 15 ноября 11 г.
5. Backbone.js - структура
https://github.com/codebrew/backbone-rails
rails g backbone:scaffold Post title:string content:string
1. Models - компонент, позволяющий организовать обмен
данными, предоставляет события(изменение, добавление...), на
которые могут подписываться Views
2. Routers - Его назначение обработка хеш навигации в приложении. В
современных браузерах это прямое управление адресной строкой, в
остальных - эмуляция через якорные ссылки(#..., настраиваемо)
3. Templates - в общем-то любой шаблонизатор(встроенный в
Underscore, EJS, JQTemplates, Mustache, Handlabars)
4. Views - ООП подход, те каждая вью отвечает за
определенный блок на странице. Если блоков несколько - то
будет несколько экземпляров вью, каждый из который хранит в
себе конкретную информацию(настройку) на логический блок.
Ограничений нет - блоки логические.
вторник, 15 ноября 11 г.
6. 1. Router
class Apihelp.Routers.PostsRouter extends Backbone.Router Структура роутера:
initialize: (options) -> 1. Хеш(функция, возращающая хеш) - определяет урл и соответствующее
@posts = new Apihelp.Collections.PostsCollection() ему действие обработчик
@posts.reset options.posts 2. Набор функций обработчиков - на вход получают параметры, указанные
в определении URL.
routes:
"/new" : "newPost"
"/index" : "index"
"/:id/edit" : "edit"
"/:id" : "show"
".*" : "index"
newPost: ->
@view = new Apihelp.Views.Posts.NewView(collection: @posts)
$("#posts").html(@view.render().el)
index: ->
@view = new Apihelp.Views.Posts.IndexView(posts: @posts)
$("#posts").html(@view.render().el)
show: (id) ->
post = @posts.get(id)
@view = new Apihelp.Views.Posts.ShowView(model: post)
$("#posts").html(@view.render().el)
edit: (id) ->
post = @posts.get(id)
@view = new Apihelp.Views.Posts.EditView(model: post)
$("#posts").html(@view.render().el)
вторник, 15 ноября 11 г.
7. 2. View
Структура View:
Apihelp.Views.Posts ||= {}
1. View наследуется от базового класса Baclbone.View, но может
class Apihelp.Views.Posts.EditView extends Backbone.View
template : JST["backbone/templates/posts/edit"] насловедоваться и от другой вью
events :
"submit #edit-post" : "update"
update : (e) ->
e.preventDefault() 2. Шаблонизатор можно использовать любой, рекомендую
e.stopPropagation() Mustache(Hadlebars). Определять явно не обязательно, но удобно поскольку
сразу видно какие шаблоны используются в данной вью.
@model.save(null,
success : (post) =>
@model = post
window.location.hash = "/#{@model.id}"
) 3. Хеш реакций на события - позволяет определять любые события внутри
html блока вью(нет просмотра всего DOM страницы, только относительно
render : -> текущей view - для работы с DOM вью также есть сокращение this.$()) и
$(this.el).html(this.template(@model.toJSON() )) функций обработчиков. В каждый обработчик передает конктекс текущей
View(this) и пераметр, имеющий всю нужную информацию об источнике
this.$("form").backboneLink(@model) события.
return this
4. Набор обработчков событий и просто служебных функций
вторник, 15 ноября 11 г.
8. 3. Model && Collection
Модель - предназначена для хранения логики, относящейся к конкретному
объекту - преобразования, валидации, кастомная логика, свойства и
собственно структура объектов
Коллекция - упорядоченный найбор объекто моделей. Предоставляет
события об изменения в моделях, появлении новых и пр. Предоставляет
методы для обновления, сохранения, сравнения данных, включая
взимодействие с сервером
class Apihelp.Models.Post extends Backbone.Model
paramRoot: 'post'
defaults:
title: null
content: null
Существуют множество реализаций моделей и их способом взиамодействия
class Apihelp.Collections.PostsCollection extends с сервером - rest api(rails), websocket и другие
Backbone.Collection
model: Apihelp.Models.Post
url: '/posts'
Интегрированы методы Underscore.js, для обработки наборов моделей
вторник, 15 ноября 11 г.
9. 4. Templates
Backbone дает свободу выбора шаблонизатора(Jquery Templates, Underscore,
EJS,Mustache, и еще тонна существующих)
<h1>Edit post</h1>
<form id="edit-post" name="post">
<div class="field">
<label for="title"> title:</label>
<input type="text" name="title" id="title" value={{ title }} >
</div>
НО! Самый удобный способ - когда шаблоны на стороне сервера
<div class="field"> компилируются в один файл, содержащий JS функций, собранный в
<label for="content"> content:</label> массив(JST):
<input type="text" name="content" id="content" - не загрязняется html
value={{ content }} > - систематизация позволяет динамически конструировать вызовы шаблонов
</div>
<div class="actions">
<input type="submit" value="Update Post" />
</div>
</form>
<a href="#/index">Back</a> Rails.version <3.1 => Jammit
Rails.version >=3.1 => AssetPipeline(HadleBars + HadleBars Assets) || Jammit
вторник, 15 ноября 11 г.
10. To sum up:
1MVC(Backbone) - не панацея. Это удобный инстурмент,
когда JS кода много.
2. Backbone - позволяет структурировать JS код по типу
Rails приложения, что облегчает его поддержку и развитие
3. События позволяют сделать код слабо связанным -
облегчает структура приложения
4. Production ready
THE END
вторник, 15 ноября 11 г.