Главная концепция - держать данные отдельно от ДОМа страницы, так креши во вью не приводят к потерям данных на странице.
Получить JSON из модели:
change
focusout
mousedown
mouseover
select
click
hover
mouseenter
mouseup
unload
dblclick
keydown
mouseleave
ready
focus
keypress
mousemove
resize
focusin
load
mouseout
scroll
Встроенные:
add, remove, reset
События запущенные в модели, также будут срабатывать в колекции:
change, change: <attr>, destroy, sync, error, all
Пример приложения:
https://upcase.com/backbone-js-on-rails
http://recipeswithbackbone.com/
http://ricostacruz.com/backbone-patterns/
https://github.com/codeschool-courses/anatomyofbackbone
Создание модели
var MyModel = Backbone.Model.extend({});
var myModel = new MyModel({myField: "..."});
myModel.set('myField', 'some value');
Создание вьюхи:
var MyView = Backbone.View.extend({
render: function(){
$(this.el).html('<li>' + this.model.get('myField') + '</li>
');
}
});
var myView = new MyView({model: myModel});
myView.render();
$('#app').html(myView);
Модель
Получение данных с сервера в модель и обратно
Хард вей:)
myModel.url = '/someurl';
myModel.fetch();
alert(myModel.get('field1'));
RESTful way(CRUD):
var TodoItem = Backbone.Model.extend({urlRoot: '/todos'});
var todoItem = new TodoItem({id: 1});
todoItem.fetch();//GET /todos/1
//--> { id: 1, description: 'Pick up milk', status: 'incomplete' }
todoItem.set({description: 'Pick up cookies.'});
todoItem.save();//PUT /todos/1 with JSON params
var todoItem2 = new TodoItem();
todoItem2.set({description: 'Fill prescription.'});
todoItem2.save();//POST /todos with JSON params
todoItem2.get('id');//-->2
todoItem2.destroy();//DELETE /todos/2
Получить JSON из модели:
todoItem.toJSON();
//--> { "id": "1", "description": "Pick up milk", "status": "incomplete" }
Значения по-умолчанию:
var TodoItem = Backbone.Model.extend({
defaults: {
description: 'Empty todo...',
status: 'incomplete',
date: new Date()//each item gets one time
}
});
var TodoItem = Backbone.Model.extend({
defaults: function(){
return {
description: 'Empty todo...',
status: 'incomplete',
date: new Date()//each item gets time of its creation
};
}
});
Ивенты:
Build-in:
var doThing = function() {
...
};
todoItem.on('change', doThing);
todoItem.set({description: 'Fill prescription.'});//Event triggered on change
todoItem.set({description: 'Fill prescription.'}, {silent: true});//Set without triggering event
todoItem.off('change', doThing);
| change | When an attribute is modified |
| change:<attr> | When <attr> is modified |
| destroy | When a model is destroyed |
| sync | Whenever successfully synced |
| error | When model save or validation fails |
| all | Any triggered event |
Кастомные
todoItem.on('event-name', function(){
alert('event-name happened!');
});
todoItem.trigger('event-name');
View
Мо умолчанию обвертка div, но мы можем поменять:
var SimpleView = Backbone.View.extend({tagName: 'li'});
var simpleView = new SimpleView();
console.log(simpleView.el);//--> <li></li>
И с детальками:
var TodoView = Backbone.View.extend({
tagName: 'article',
id: 'todo-view',
className: 'todo'
});
var todoView = new TodoView();
console.log(todoView.el);
//--> <article id="todo-view" class="todo"></article>
Backbone по-умолчанию испльзует underscore lib для шаблонов:
var TodoView = Backbone.View.extend({
...
template: _.template('<h3'><%= description %><h3>'),
render: function(){
var attributes = this.model.toJSON();
this.$el.html(this.template(attributes));//чтобы пользоваться $el, нужно чтобы был подгружен jQuery
}
});
События во вью:
var TodoView = Backbone.View.extend({
events: {
"click h3": "alertStatus"
},
alertStatus: function(e){
alert('Hey you clicked the h3!');
}
});
// внутри this.$el.delegate('h3', 'click', alertStatus);
var SampleView = Backbone.View.extend({
events: {
"<event> <selector>": "<method>"
},
...
});
Когда подключен jQuery View может работать со следующими событиями:change
focusout
mousedown
mouseover
select
click
hover
mouseenter
mouseup
unload
dblclick
keydown
mouseleave
ready
focus
keypress
mousemove
resize
focusin
load
mouseout
scroll
Взаимоподвязка модели и вьюхи.
var AppointmentView = Backbone.View.extend({
template: _.template('<span class="<% if(cancelled) print("cancelled") %>">' +
'<%= title %></span>' +
'<a href="#">x</a>'),
events: { "click a": "cancel" },
initialize: function(){
this.model.on('change', this.render, this);
},
cancel: function(){
this.model.cancel();
},
render: function(){
this.$el.html(this.template(this.model.toJSON()));
}
});
Колекции
var TodoList = Backbone.Collection.extend({
model: TodoItem
});
Возможные операции:todoList.length;//-->2
todoList.add(todoItem1);
todoList.at(0);//at index
todoList.get(1);//by id
todoList.remove(todoItem1);
todoList.reset([
{description: 'Pick up milk', status: 'incomplete'},
{description: 'Get a car wash', status: 'incomplete'},
{description: 'Learn Backbone', status: 'incomplete'}
]);//колекция заполняется указанными моделями и стирает все что в ней было
Получать JSON данные из сервера:
var TodoList = Backbone.Collection.extend({
url: '/todos'
});
todoList.fetch();// GET /todos
/* [
* {description: 'Pick up milk', status: 'incomplete', id: 1},
* {description: 'Get a car wash', status: 'incomplete', id: 2}
* ]
*/
todoList.length; //-->2
События:
//listen for reset
todoList.on('reset', doThing);
//Event triggered on reset & fetch
todoList.fetch();
todoList.reset();
//without notification
todoList.fetch({silent: true});
todoList.reset({silent: true});
add, remove, reset
События запущенные в модели, также будут срабатывать в колекции:
change, change: <attr>, destroy, sync, error, all
Манипуляции с колекцией
Функции из underscorejs для колекции поставлены вместе с бекбоновской колекцией.Views & Collections
Колекция ничего не отрисовывывает сама, она все делегирует моделям каждого елемента, а они уже каждой своей вьюшке.var Appointment = Backbone.Model.extend({});
var AppointmentView = Backbone.View.extend({
initialize: function(){
this.model.on('hide', function(){
this.remove();
}, this);
},
template: _.template('<span class="<%= if(cancelled) print("cancelled") %>">' +
'<%= title %></span>' +
'<a href="#">x</a>'),
render: function(){
this.$el.html(this.template(this.model.toJSON()));
return this;
},
remove: function(){
this.$el.remove();
}
};
var AppointmentList = Backbone.Collection.extend({
model: Appointment,
initialize: function(){
this.on('remove', function(model){
model.trigger('hide');
});
}
});
var appointments = new AppointmentList();
var AppointmentListView = Backbone.View.extend({
initialize: function(){
this.collection.on('add', this.addOne, this);
this.collection.on('reset', this.render, this);
},
render: function(){
this.collection.forEach(this.addOne, this);
},
addOne: function(model){
var appointmentView = new AppointmentView({model: model});
this.$el.append(appointmentView.render().el);
}
});
var appointmentsView = new AppointmentListView({
collection: appointments
});
$('#app').html(appointmentsView.render().el);
Router & History
Router
var router = new Backbone.Router({
routes: {
'todos': 'index',//when the url path is /todos or #todos
'todos/:id': 'show'
},
index: function(){...},
show: function(id){...}
});
| matcher | URL | params |
|---|---|---|
| search/:query | search/ruby | query='ruby' |
| search/:query/p:page | search/ruby/p2 | query='ruby', page=2 |
| folder/:name-:mode | folder/foo-r | query='foo', mode='r' |
| file/*path | file/hello/world.txt | path='hello/world.txt' |
History
Backbone.history.start();
router.navigate('todos/1');//-->#todos/1
Backbone.history.start({pushState: true});//HTML5 Push State
router.navigate('todos/1', {trigger: true});//-->/todos/1
Пример приложения:
var TodoRouter = Backbone.Router.extend({
routes: {
"": "index",
"todos/:id": "show"
},
index: function(){
this.todoList.fetch();
},
show: function(id){
this.todoList.focusOnTodoItem(id);
},
initialize: function(options){
this.todoList = options.todoList;
}
});
var todoList = new TodoList();
var TodoApp = new TodoRouter({todoList: todoList});
Или вот так:
var TodoApp = new (Backbone.Router.extend({
routes: {
"": "index",
"todos/:id": "show"
},
initialize: function(options){
this.todoList = new TodoList();
this.todosView = new TodoListView({collection: this.todoList});
$('#app').append(this.todosView.el);
},
start: function(){
Backbone.history.start({pushState: true});
},
index: function(){
this.todoList.fetch();
},
show: function(id){
this.todoList.focusOnTodoItem(id);
}
}));
...
//and on page
$(function(){ TodoApp.start(); });
https://upcase.com/backbone-js-on-rails
http://recipeswithbackbone.com/
http://ricostacruz.com/backbone-patterns/
https://github.com/codeschool-courses/anatomyofbackbone
Комментариев нет:
Отправить комментарий