-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBackbone.php
More file actions
352 lines (263 loc) · 16.5 KB
/
Backbone.php
File metadata and controls
352 lines (263 loc) · 16.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
<?
Урок 1. Введение.
BackboneJS - JavaScript флеймворк, основаный на паттерне MV*. Используется для больших проектов,
что бы избежать груды запутанного jQuery кода(структурировать код).
Model - содержит события и JSON данные приложения(атребуты), а также логику для работы с ними:
вычисляемые свойства, валидация, права доступа. Модель может хранится как в браузере,
так и в базе данных на сервере. Collection - упорядоченная группа моделей.
View - содержит логику отображения данных модели и коллекций. View - позволяет отделить данные
от их конкретного отображения в DOM, что позволяет отображать одни и теже даннные в разных представлениях,
и реагировать ВСЕМ предтавлениям на изменения модели.
Controller — промежуточный слой между моделью и представлением, предназначенный для обмена данными между ними.
Урок 2. Основы.
Backbone состоит из 4-х основных классов:
Model (Модель)
Collection (Коллекция)
View (Представление)
Router (Роутер)
Backbone работает в связке с Underscore, который предназначен для более простой работы с
объектами, функциями, массивами.
Урок 3. Model
3.1 Создание прототипа модели.
Создание пустого объекта:
var Book = Book || {};
Наследуемся от главной модели
Book = Backbone.Model.extend({}); // Создаем прототип (наследуемся)
Создаем экземпляр:
var oBook = new Book({ title: 'Alice in Wonderland', author: 'Lewis Caroll' });
3.2 Стандартные поля - свойства объекта, которые мы можем определить при его создании.
Пример:
Book = Backbone.Model.extend({
default: {
title: 'No title',
author: 'unknown',
releaseDate: 2011,
description: ''
}
});
3.2 Методы
Существуют стандартные методы, для работы с моделью:
Initialize - вызывается после создания экземпляра класса.
Пример:
var Book = Backbone.Model.extend({
initialize: function() {
console.log('Object book created');
}
});
Get - считывание атребута
var BookTitle = oBook.get('title');
Set - запись атребута
oBook.set({ releaseDate: '1865'});
Save - сохранение данных модели на сервер. При создании объекта - POST, обновлении - PUT
Урок 4. СОБЫТИЯ
4.1 Создание и вызов событий.
Пример:
var object = {}; // Создаем пустой объект
_.extend(object, Backbone.Events); // Расширяем наш объект возможностями объекта Backbone.Events при помощи Underscore
// Теперь унас появилась возможность слушать и вызывать события
object.on("alert", function(msg) { // Слушаем событие с именем "alert" и вызываем функцию. (event, callback, [context])
alert("Сработало " + msg);
});
object.trigger("alert", "событие"); // Вызываем событие (event, [*args])
!!!Слушателей у одного события может быть много.
Можно привязать событие к кнопке. И при клике вызывать событие.
$('#btn').on('click', function() {
object.trigger("alert", "событие по клику"); // Вызываем событие.
});
!!!Если в качестве имени события написать "all", то это событие будет возникать при вызове любого события.
И в функцию, первым параметром, прийдёт имя вызванного события.
Данные в обработчик можно передавать через хэш:
object.on({
"change:title": titleView.update,
"change:author": authorPane.update,
"destroy": bookView.remove
});
4.2 Удаление обработчиков.
object.off([event], [callback], [context])
Если не указан контекст - будут удалены все версии обработчика.
Если не указан обработчик - будут удалены все обработчики для указанного события.
Если не указано событие - будут удалены ВСЕ обработчики.
// Удаляет только обработчик `onChange`.
object.off("change", onChange);
// Удаляет все обработчики события "change".
object.off("change");
// Удаляет все обработчики `onChange` для всех событий.
object.off(null, onChange);
// Удаляет все обработчики в контексте `context` для всех событий.
object.off(null, null, context);
// Удаляет все обработчики для объекта `object`.
object.off();
4.3 Метод once - тот же on но срабатывает всего один раз.
object.once(event, callback, [context])
4.4 Метод - listenTo - указывает оъекту прослушивать событие другого объекта.
Преимущество этого метода над ON в том, что затем можно удалить все события сразу.
object.listenTo(other, event, callback)
4.4 Метод - listenToOnce - тот же listenTo, только одноразовый.
object.listenToOnce(other, event, callback)
4.5 Метод - stopListening - Прекращает прослушивание события у объекта.
Вызов метода stopListening без аргументов удалит все зарегистрированные обработчики.
Также можно указать определённый объект, событие или обработчик.
4.6 Каталог событий - список всех встроенных событий, которые может запускать Backbone.js
"add" (model, collection, options) — когда модель добавляется в коллекцию.
"remove" (model, collection, options) — когда модель удаляется из коллекции.
"reset" (collection, options) — когда всё содержимое коллекции заменяется.
"sort" (collection, options) — когда коллекция была отсортирована.
"change" (model, options) — когда атрибут модели меняется.
"change:[attribute]" (model, value, options) — когда меняется конкретный атрибут модели.
"destroy" (model, collection, options) — когда модель уничтожена.
"request" (model, xhr, options) — когда модель (или коллекция) отправляет запрос на сервер.
"sync" (model, resp, options) — когда модель была успешно синхронизирована с сервером.
"error" (model, xhr, options) — когда вызов save провалился на сервере.
"invalid" (model, error, options) — модель не прошла валидацию на клиенте.
"route:[name]" (params) — когда один конкретный роут находит соответствие.
"route" (router, route, params) — когда любой из роутов находит соответствие.
"all" — это специальное событие срабатывает каждый раз, когда срабатывает любое событие, передавая имя события первым аргументом.
ПРИМЕР РАБОТЫ С МОДЕЛЬЮ И СОБЫТИЯМИ
app.classRocket = Backbone.Model.extend({ // Наследуемся от главной модели Backbone
defaults: { // Устанавливаем стандартные значения
name: "name",
description: "-",
size: 100
},
initialize: function () { // Описываем метод, вызываемый после создания экземпляра класса
console.log('obj created');
this.on('change', function () { // Навешиваем событие на изменение объекта
console.log('obj changed');
var json = this.changedAttributes(); // Возвращаем JSON(хэш) только измененных параметров
console.log(json);
});
},
validate: function (attrs) { // Метод отбора данных, что бы они были актуальны
if(attrs.size>1000) {
console.log('Incorrect size');
return 'Incorrect size';
}
},
increaseSize: function () { // Пользовательская функция, для увеличения размера.
this.set({ // Устанавливаем значение свойству
size: this.get('size')+100 // Вытаскиваем текущее значение, изменяем его и отдаем.
}, {validate:true}); // передаем наш валидатор
}
});
// Работа с экземпляром
app.rocket = new app.classRocket({ // Создаем экземпляр класса, переопределяем дефолтные значения
name: "rocket",
description: "super"
});
app.rocket.set({ // Изменяем свойства объекта
size: 250,
type: 'active' // Добавляем новое свойство
});
$('#btn').on('click', function () { // Навешиваем на кнопку событие с нашей пользовательской функцией.
app.rocket.increaseSize();
});
Урок 5. View
По-русски его называют «вид» или «представление», и нужны он главным образом для того,
чтобы отображать в браузере изменения(change) модели, коллекций и реагировать на события, вроде click, submit и пр.
Пример
SearchView = Backbone.View.extend({
initialize: function() {
alert(‘Initialized!’);
}
});
var searchView = new SearchView();
5.1 Свойство el - ссылка на DOM элемент. Сначала формируется отображение в el а затем он уже вставляется на страницу.
!!!Все представления должны быть связаны с DOM-элементом, если не определить свойство el то backbone сам создаст новый элемент.
Управлять созданием элемента можно 3-мя свойствами: tagName, className, id.
Если ни один из них не задан - будет создан пустой div.
Также, для вызова jQuery существует свойство $el, которое хранить хэш объекта.
Например - привяжем наше представлдение к кнопке:
var searchView = new SearchView({ el: $('#btn') });
5.2 Рендеринг представления
Что бы наше представление появилось в DOM - необходимо реализовать метод render, и вызвать его при создании.
SearchView = Backbone.View.extend({
initialize: function() {
alert('Initialized!');
},
render: function() {
var template = _.template($('#search_template').html(), {}); // ищем наш шаблон по айди
this.$el.html(template);
return this;
}
});
var searchView = new SearchView({ el: $('#search_container') });
5.3 Templater - шаблонизатор
Пример:
<script>
$(function() {
var compiled = _.template($('#rocketTpl').html());
var obj = {
name: 'Super',
size: 190,
color: 'red',
nice: true
};
$('#rocket').append(compiled(obj));
});
</script>
<script type="text/template" id="rocketTpl">
<div>Name: <%= name %></div>
<div>Size: <%= size %></div>
<div>Color: <%= color %></div>
<% if(nice) { %>
<div>Nice Obj</div>
<% } %>
</script>
Урок 6. Коллекции - группа моделей.
var MyModel = Backbone.Model.extend({ // Создаём прототип(класс) модели
defaults: {
size:10
}
});
var MyCollection = Backbone.Collection.extend({ // Создаём прототип(класс) коллекции
model:MyModel
});
var coll = new MyCollection(); // Создаем экземпляр коллекции (можно уже при создании передать объект)
var car = new MyModel({ // Создаем экземпляр модели, которую затем можем добавить в коллекцию.
size: 75
});
// Добавление моделей
coll.add(car); // Добавляем уже созданную модель в коллекцию
coll.add({}); // Добавляем пустой объект, будет использоваться модель по умолчанию
coll.add([ {size:80}, {color:'white'}, {} ]) // Добавляем массив объектов в коллекцию.
// Удаляем модель из коллекции
coll.remove(car);
// Вывод коллекции
coll.toJSON();
Урок 7. Роутеры - предназначены для маршрутизации на стороне клиента, а также связывания этих действий с событиями.
!!!При инициализации роутера обязательно нужно вызвать
Backbone.history.start()
чтобы задать начальное состояние приложения.
Пример:
var Router = Backbone.Router.extend({
routes: { // ИМ РОУТЕРЕРОВ НЕ МОЖЕТ НАЧИНАТСЯ СО СЛЕША!!!
"": "first", // Пустая ссылка
"first(/)": "first", // Ссылка с слешом в конце, и без - разные ссылки. Для одного роута нужно / обернуть в ()
"first/:query": "first", // Ссылка + параметп
"first/:query/:category":"first", // Ссылка + 2 параметра
"second": "second",
"third": "third",
"file/*path" "searchFile" // #file/любой текст, в searchFile будет передано ~ : nested/folder/file.txt
},
initialize: function() {
Backbone.history.start(); // Задаем начальное состояние
},
first: function(query,category) { // Описываем функцию, если переданы параметры - они в неё приходят
console.log(query,category);
}
!Можно в ручную переходить по ссылкам:
app.router.navigate("first", {trigger: true}); // trigger передаём, что бы сработала одна из функций роутера
!При переходах - Роутер генерирует события, одноименные с именем роута, следовательно это можно отследить.
Router.on('page:1', function() {
console.log('page 1');
});
Можно добавить роуты в уже созданный экземпляр при помощи метода route:
router.route(route, name, [callback])
!!! Также доступны роуты в виде regexp
initialize: function(options) {
// совпадает с #page/10, в function будет передано "10"
this.route("page/:number", "page", function(number){ ... });
// совпадает с /117-a/b/c/open, в this.open будет передано "117-a/b/c"
this.route(/^(.*?)\/open$/, "open");
},
open: function(id) {}