-
1.
Радослав Станков
OpenFest 05/11/2011
-
2.
Кой съм аз?
@rstankov
http://rstankov.com
http://github.com/rstankov
-
3.
Browser
Controller
Model View
Сървър
-
4.
Browser
Controller
Model View
Сървър
-
5.
Browser
Controller
Model View
Сървър
-
6.
Browser
Controller
Model View
Сървър
-
7.
Browser
Controller
Model View
Сървър
-
8.
Browser
Controller
Model View
Сървър
-
9.
Browser
Controller
Model View
Сървър
-
10.
Browser
Controller
Model View
Сървър
-
11.
Browser
Controller
Model View
Сървър
-
12.
Browser
Controller
Model View
Сървър
-
13.
Browser
Controller
Model View
Сървър
-
14.
Browser
Controller
Model View
Сървър
-
15.
Browser
Controller
Model View
Сървър
-
16.
Browser
Dom
View
Model
-
17.
Browser
Dom
View
Model
-
18.
Browser
Dom
View
Model
-
19.
Browser
Dom
View
Model
-
20.
Browser
Dom
View
Model
-
21.
Browser
Dom
View
Model
-
22.
Browser
Dom
View
Model
-
23.
Browser
Dom
View
Model
-
24.
Browser
Dom
View
Model
-
25.
Backbone.Events
-
26.
var object = {};
$.extend(object, Backbone.Events);
object.bind('eventName', function() {
console.log('1');
});
object.bind('eventName', function() {
console.log('2');
});
object.trigger('eventName');
// prints '1' and '2'
-
27.
var object = {};
$.extend(object, Backbone.Events);
object.bind('eventName', function() {
console.log('1');
});
object.bind('eventName', function() {
console.log('2');
});
object.trigger('eventName');
// prints '1' and '2'
-
28.
var object = {};
$.extend(object, Backbone.Events);
object.bind('eventName', function() {
console.log('1');
});
object.bind('eventName', function() {
console.log('2');
});
object.trigger('eventName');
// prints '1' and '2'
-
29.
var object = {};
$.extend(object, Backbone.Events);
object.bind('eventName', function() {
console.log('1');
});
object.bind('eventName', function() {
console.log('2');
});
object.trigger('eventName');
// prints '1' and '2'
-
30.
var object = {};
$.extend(object, Backbone.Events);
object.bind('eventName', function() {
console.log('1');
});
object.bind('eventName', function() {
console.log('2');
});
object.trigger('eventName');
// prints '1' and '2'
-
31.
Backbone.Model
-
32.
var Person = Backbone.Model.extend({
initialize: function(){
console.log("I'm alive!");
}
});
new Person();
-
33.
var Person = Backbone.Model.extend({
initialize: function(){
console.log("I'm alive!");
}
});
new Person();
-
34.
var Person = Backbone.Model.extend({
initialize: function(){
console.log("I'm alive!");
}
});
new Person();
-
35.
var Person = Backbone.Model.extend({});
var me = new Person({name: 'Radoslav'});
me.get('name'); // Radoslav
me.set({lastName: 'Stankov'});
me.get('lastName'); // Stankov
-
36.
var Person = Backbone.Model.extend({});
var me = new Person({name: 'Radoslav'});
me.get('name'); // Radoslav
me.set({lastName: 'Stankov'});
me.get('lastName'); // Stankov
-
37.
var Person = Backbone.Model.extend({});
var me = new Person({name: 'Radoslav'});
me.get('name'); // Radoslav
me.set({lastName: 'Stankov'});
me.get('lastName'); // Stankov
-
38.
var Person = Backbone.Model.extend({});
var me = new Person({name: 'Radoslav'});
me.get('name'); // Radoslav
me.set({lastName: 'Stankov'});
me.get('lastName'); // Stankov
-
39.
var Person = Backbone.Model.extend({});
var me = new Person({name: 'Radoslav'});
me.get('name'); // Radoslav
me.set({lastName: 'Stankov'});
me.get('lastName'); // Stankov
-
40.
var Person = Backbone.Model.extend({
defaults: {
name: 'John',
lastName: 'Doe',
}
});
var me = new Person();
me.get('name'); // John
me.get('lastName'); // Doe
-
41.
var Person = Backbone.Model.extend({
defaults: {
name: 'John',
lastName: 'Doe',
}
});
var me = new Person();
me.get('name'); // John
me.get('lastName'); // Doe
-
42.
var Person = Backbone.Model.extend({
defaults: {
name: 'John',
lastName: 'Doe',
}
});
var me = new Person();
me.get('name'); // John
me.get('lastName'); // Doe
-
43.
var Person = Backbone.Model.extend({
defaults: {
name: 'John',
lastName: 'Doe',
}
});
var me = new Person();
me.get('name'); // John
me.get('lastName'); // Doe
-
44.
var Calculator = Backbone.Model.extend({
defaults: {
value: 0
},
value: function(){
return this.get('value');
},
sum: function(value){
this.set({value: value + this.get('value')});
},
reset: function(){
this.set({value: 0});
}
});
-
45.
var Calculator = Backbone.Model.extend({
defaults: {
value: 0
},
value: function(){
return this.get('value');
},
sum: function(value){
this.set({value: value + this.get('value')});
},
reset: function(){
this.set({value: 0});
}
});
-
46.
var Calculator = Backbone.Model.extend({
defaults: {
value: 0
},
value: function(){
return this.get('value');
},
sum: function(value){
this.set({value: value + this.get('value')});
},
reset: function(){
this.set({value: 0});
}
});
-
47.
var Calculator = Backbone.Model.extend({
defaults: {
value: 0
},
value: function(){
return this.get('value');
},
sum: function(value){
this.set({value: value + this.get('value')});
},
reset: function(){
this.set({value: 0});
}
});
-
48.
var Calculator = Backbone.Model.extend({
defaults: {
value: 0
},
value: function(){
return this.get('value');
},
sum: function(value){
this.set({value: value + this.get('value')});
},
reset: function(){
this.set({value: 0});
}
});
-
49.
var cal = new Calculator();
cal.bind('change:value', function(model, value){
console.log(value);
});
cal.bind('change', function(model){
console.log(model.get('value'));
});
cal.bind('all', function(eventName) {
console.log('I see every thing!', eventName);
});
-
50.
var cal = new Calculator();
cal.bind('change:value', function(model, value){
console.log(value);
});
cal.bind('change', function(model){
console.log(model.get('value'));
});
cal.bind('all', function(eventName) {
console.log('I see every thing!', eventName);
});
-
51.
var cal = new Calculator();
cal.bind('change:value', function(model, value){
console.log(value);
});
cal.bind('change', function(model){
console.log(model.get('value'));
});
cal.bind('all', function(eventName) {
console.log('I see every thing!', eventName);
});
-
52.
var cal = new Calculator();
cal.bind('change:value', function(model, value){
console.log(value);
});
cal.bind('change', function(model){
console.log(model.get('value'));
});
cal.bind('all', function(eventName) {
console.log('I see every thing!', eventName);
});
-
53.
var cal = new Calculator();
cal.bind('myEvent', function(){
console.log('KaBoom....');
});
cal.trigger('myEvent');
-
54.
var Product = Backbone.Model.extend({
urlRoot: '/products'
});
var chair = new Product({
name: 'chair',
price: 10
});
chair.save();
// POST /products
-
55.
var Product = Backbone.Model.extend({
url: function(){
return '/products/' + (this.isNew() ? '' : this.id);
}
});
var chair = new Product({
id: 5,
name: 'chair',
price: 10
});
chair.save();
// PUT /products/1
-
56.
http://documentcloud.github.com/backbone/#Model-save
-
57.
И още...
• validate
• escape
• has
• unset
• clear
• hasChanged
• changedAttributes
• previousAttributes
• fetch
• toJSON
• clone
-
58.
Backbone.View
-
59.
var UserNameView = Backbone.View.extend({
tagName: 'input',
className: 'string optional',
id: 'user-name',
attributes: {
type: 'string',
name: 'user[name]'
}
});
var userName = new UserNameView();
console.log(userName.el);
<input type="string" name="user[name]" id="user-name" class="string optional">
-
60.
var UserNameView = Backbone.View.extend({
tagName: 'input',
className: 'string optional',
id: 'user-name',
attributes: {
type: 'string',
name: 'user[name]'
}
});
var userName = new UserNameView();
console.log(userName.el);
<input type="string" name="user[name]" id="user-name" class="string optional">
-
61.
var UserNameView = Backbone.View.extend({
tagName: 'input',
className: 'string optional',
id: 'user-name',
attributes: {
type: 'string',
name: 'user[name]'
}
});
var userName = new UserNameView();
console.log(userName.el);
<input type="string" name="user[name]" id="user-name" class="string optional">
-
62.
var UserNameView = Backbone.View.extend({
tagName: 'input',
className: 'string optional',
id: 'user-name',
attributes: {
type: 'string',
name: 'user[name]'
}
});
var userName = new UserNameView();
console.log(userName.el);
<input type="string" name="user[name]" id="user-name" class="string optional">
-
63.
var UserNameView = Backbone.View.extend({
tagName: 'input',
className: 'string optional',
id: 'user-name',
attributes: {
type: 'string',
name: 'user[name]'
}
});
var userName = new UserNameView();
console.log(userName.el);
<input type="string" name="user[name]" id="user-name" class="string optional">
-
64.
var UserNameView = Backbone.View.extend({
tagName: 'input',
className: 'string optional',
id: 'user-name',
attributes: {
type: 'string',
name: 'user[name]'
}
});
var userName = new UserNameView();
console.log(userName.el);
<input type="string" name="user[name]" id="user-name" class="string optional">
-
65.
var UserNameView = Backbone.View.extend({
tagName: 'input',
className: 'string optional',
id: 'user-name',
attributes: {
type: 'string',
name: 'user[name]'
}
});
var userName = new UserNameView();
console.log(userName.el);
<input type="string" name="user[name]" id="user-name" class="string optional">
-
66.
var UsersListView = Backbone.View.extend({
el: '#users-list'
});
var userList = new UsersListView();
console.log(userList.el);
-
67.
var EditBoxView = Backbone.View.extend({});
var element = $('#edit-box-view').get(0),
editBox = new EditBoxView({el: element});
console.log(editBox.el === element);
-
68.
var DocumentView = Backbone.View.extend({
events: {
'dblclick': 'open',
'click .grid .doc': 'select',
'customEvent .title': 'custom'
},
open: function() {},
select: function() {},
custom: function() {}
});
-
69.
var DocumentView = Backbone.View.extend({
events: {
'dblclick': 'open',
'click .grid .doc': 'select',
'customEvent .title': 'custom'
},
open: function() {},
select: function() {},
custom: function() {}
});
-
70.
var DocumentView = Backbone.View.extend({
events: {
'dblclick': 'open',
'click .grid .doc': 'select',
'customEvent .title': 'custom'
},
open: function() {},
select: function() {},
custom: function() {}
});
-
71.
var DocumentView = Backbone.View.extend({
events: {
'dblclick': 'open',
'click .grid .doc': 'select',
'customEvent .title': 'custom'
},
open: function() {},
select: function() {},
custom: function() {}
});
-
72.
var DocumentView = Backbone.View.extend({
events: {
'dblclick': 'open',
'click .grid .doc': 'select',
'customEvent .title': 'custom'
},
open: function() {},
select: function() {},
custom: function() {}
});
-
73.
var DocumentView = Backbone.View.extend({
events: {
'dblclick': 'open',
'click .grid .doc': 'select',
'customEvent .title': 'custom'
},
open: function() {},
select: function() {},
custom: function() {}
});
-
74.
var DocumentView = Backbone.View.extend({
events: {
'dblclick': 'open',
'click .grid .doc': 'select',
'customEvent .title': 'custom'
},
open: function() {},
select: function() {},
custom: function() {}
});
-
75.
<script type="text/template" id="news">
<h1><%= title %></h1>
<time><%= created_at %></time>
<p><%= text %></p>
</script>
-
76.
var NewsView = Backbone.View.extend({
template: _.template($('#news').html()),
render: function() {
this.el.innerHTML = this.template(this.model);
return this;
}
});
-
77.
var view = new NewsView({
model: {
title: "News Title",
created_at: "Today",
text: "Long text"
}
});
document.body.appendChild(view.render().el);
-
78.
<script type="text/template" id="news">
<h1><%= title %></h1>
<time><%= created_at %></time>
<p><%= text %></p>
</script>
-
79.
<div>
<h1>News Title</h1>
<time>Today</time>
<p>Long text</p>
</div>
-
80.
View
Model DOM
-
81.
View
Model DOM
-
82.
View
Model DOM
-
83.
View
Model DOM
-
84.
View
Model DOM
-
85.
View
Model DOM
-
86.
View
Model DOM
-
87.
View
Model DOM
-
88.
View
Model DOM
-
89.
View
Model DOM
-
90.
View
Model DOM
View 2
-
91.
View
Model DOM
View 2
-
92.
View
Model DOM
View 2
-
93.
View
Model DOM
View 2
-
94.
View
Model DOM
View 2
-
95.
View
Model DOM
View 2
-
96.
View
Model DOM
View 2
-
97.
View
Model DOM
View 2
-
98.
View
Model DOM
View 2
-
99.
View
Model DOM
View 2
-
100.
View
View 2
Model DOM
-
101.
View
View 2
Model DOM
View 3
-
102.
View
View 2
Model DOM
View 3
View 4
-
103.
View
View 2
Model DOM
View 3
View 4
View .. N
-
104.
View
View 2
Model DOM
View 3
View 4
View .. N
-
105.
View
View 2
Model DOM
View 3
View 4
View .. N
-
106.
View
View 2
Model DOM
View 3
View 4
View .. N
-
107.
View
View 2
Model DOM
View 3
View 4
View .. N
-
108.
View
View 2
Model DOM
View 3
View 4
View .. N
-
109.
View
View 2
Model DOM
View 3
View 4
View .. N
-
110.
View
View 2
Model DOM
View 3
View 4
View .. N
-
111.
View
View 2
Model DOM
View 3
View 4
View .. N
-
112.
Demo
-
113.
var Calculator = Backbone.Model.extend({
defaults: {
value: 0
},
increment: function() {
this.set({'value': this.get('value') + 1});
},
decrement: function() {
this.set({'value': this.get('value') - 1});
},
getValue: function() {
return this.get('value');
}
});
-
114.
var ButtonsView = Backbone.View.extend({
events: {
'click .plus': 'plus',
'click .minus': 'minus'
},
plus: function() {
this.model.increment();
},
minus: function() {
this.model.decrement();
}
});
-
115.
var DisplayView = Backbone.View.extend({
initialize: function() {
this.model.bind('change:value', this.render, this);
this.render();
},
render: function() {
this.el.innerHTML = this.model.getValue();
return this;
}
});
-
116.
var cal = new Calculator();
new ButtonsView({model: cal, el: '.buttons'});
new DisplayView({model: cal, el: '.display'});
-
117.
Backbone.Collection
-
118.
var ProductsCollection = Backbone.Collection.extend({
model: Product
});
var products = new ProductsCollection();
products.fetch();
products.bind('reset', function(list) {
console.log('Loaded', list.length, 'records');
});
-
119.
products.bind('add', function(model) {
console.log('new product added');
});
products.bind('remove', function(model) {
console.log('item product removed');
});
-
120.
И още...
• Underscore Methods
• add / remove / at
• sort / comparator
• reset
• create
• url
• toJSON
-
121.
Backbone.Router
-
122.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
123.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
124.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
125.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
126.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
127.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
128.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
129.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
130.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
131.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
132.
var AppRouter = Backbone.Router.extend({
routes: {
'pages': 'index',
'pages/search/:q': 'search',
'pages/:id': 'show'
},
initialize: function() {
console.log('initialize');
},
index: function() { /* code */ },
search: function(query) { /* code */ },
show: function(id) { /* code */ }
});
var app = new AppRouter();
Backbone.history.start();
-
133.
app.navigate('pages', true);
app.navigate('pages/search/title', true);
app.navigate('pages/3', true);
-
134.
site.com/path#pages
site.com/path#pages/search/title
site.com/path#pages/3
-
135.
Backbone.history.start({pushState: true});
-
136.
site.com/path#pages
site.com/path#pages/search/title
site.com/path#pages/3
-
137.
site.com/path/pages
site.com/path/pages/search/title
site.com/path/pages/3
-
138.
Недостатъци
-
139.
Алтернативи
-
140.
Алтернативи
-
141.
Алтернативи
-
142.
Алтернативи
-
143.
Въпроси?
-
144.
Благодаря за вниманието
@rstankov
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
Open-Close prinsible - open for extensions, close for modifications\n\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n