前端 framework backbone.js

October 18, 2013

介绍

http://baike.baidu.com/view/9630369.htm

backbone.js提供了一套web开发的框架,通过Models进行key-value绑定及custom事件处理,通过Collections提供一套丰富的API用于枚举功能,通过Views来进行事件处理及与现有的Application通过RESTful JSON接口进行交互.它是基于jquery和underscore的一个js框架。

官方: http://backbonejs.org/

Events

Events 是事件

on

用来绑定事件和会触发的函数.

一个事件可以绑定多个函数

var model = new Backbone.Model();  
// 在model对象中向自定义事件custom绑定两个函数  
model.on('custom', function(p1, p2) {  
    // todo  
});  
model.on('custom', function(p1, p2) {  
    // todo  
});

off

移除绑定的函数

// Removes just the `onChange` callback.
object.off("change", onChange);

// Removes all "change" callbacks.
object.off("change");

// Removes the `onChange` callback for all events.
object.off(null, onChange);

// Removes all callbacks for `context` for all events.
object.off(null, null, context);

// Removes all callbacks on `object`.
object.off();

trigger

触发事件

object.trigger(event, ![pic](*args))

listenTo() and stopListening()

listenTo 用来监听某个对象是否触发了某个事件

var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
var c = _.extend({}, Backbone.Events);

// add listeners to A for events on B and C
a.listenTo(b, 'anything', function(event){ console.log("anything happened"); });
a.listenTo(c, 'everything', function(event){ console.log("everything happened"); });

// trigger an event
b.trigger('anything'); // logs: anything happened

// stop listening
a.stopListening();

// A does not receive these events
b.trigger('anything');
c.trigger('everything');

stopListening 看字面也知道有什么用了

可以用这个来做小范围的消息模式.

其它

还有 once,listenTo,stopListening,listenToOnce 自己看了

內部事件

  • “add” (model, collection, options) — when a model is added to a collection.
  • “remove” (model, collection, options) — when a model is removed from a collection.
  • “reset” (collection, options) — when the collection’s entire contents have been replaced.
  • “sort” (collection, options) — when the collection has been re-sorted.
  • “change” (model, options) — when a model’s attributes have changed.
  • “change:pic” (model, value, options) — when a specific attribute has been updated.
  • “destroy” (model, collection, options) — when a model is destroyed.
  • “request” (model, xhr, options) — when a model (or collection) has started a request to the server.
  • “sync” (model, resp, options) — when a model (or collection) has been successfully synced with the server.
  • “error” (model, xhr, options) — when a model’s save call fails on the server.
  • “invalid” (model, error, options) — when a model’s validation fails on the client.
  • “route:pic” (params) — Fired by the router when a specific route is matched.
  • “route” (route, params) — Fired by the router when any route has been matched.

  • “all” — this special event fires for any triggered event, passing the event name as the first argument.

    Model

    数据模型

    toJSON

    toJSON 反回 Model 的 json 對象.

JSON.stringify(model.toJSON()) 才是反回 json 的 string

silent

传入 silent, set 时可以不触发 change 事件

var Person = new Backbone.Model();
Person.on("change:name", function() { console.log('Name changed'); });
Person.set({name: 'Andrew'});
// log entry: Name changed

Person.set({name: 'Jeremy'}, {silent: true});
// no log entry

console.log(Person.hasChanged("name"));
// true: change was recorded
console.log(Person.hasChanged(null));
// true: something (anything) has changed

validation

model 提供了校验方法.

var Todo = Backbone.Model.extend({
  defaults: {
    completed: false
  },

  validate: function(attributes){
    if(attributes.title === undefined){
        return "Remember to set a title for your todo.";
    }
  },

  initialize: function(){
    console.log('This model has been initialized.');
    this.on("invalid", function(model, error){
        console.log(error);
    });
  }
});

var myTodo = new Todo();
myTodo.set('completed', true, {validate: true}); // logs: Remember to set a title for your todo.
console.log('completed: ' + myTodo.get('completed')); // completed: false

注意, set/save 或者 unset 要设 {validate: true}才会进行校验.

invalid 事件来捕捉處理校驗失敗

也可以在建对象的时候,指定必须要校验,就不用每次set都要指定了

var emptyTodo = new Todo(null, {validate: true});
console.log(emptyTodo.validationError);

Views

el

el 是这个view的一个父 dom,可以在实例化的时候来指定

var todosView = new TodosView({el: $('#footer')});

setElement

可以用setElement来重新绑定 view 和 dom.

// We create two DOM elements representing buttons
// which could easily be containers or something else
var button1 = $('<button></button>');
var button2 = $('<button></button>');

// Define a new view
var View = Backbone.View.extend({
      events: {
        click: function(e) {
          console.log(view.el === e.target);
        }
      }
    });

// Create a new instance of the view, applying it
// to button1
var view = new View({el: button1});

// Apply the view to button2 using setElement
view.setElement(button2);

button1.trigger('click'); 
button2.trigger('click'); // returns true

render

整模板的时候用到

events

可以在 view 中按'eventName selector': 'callbackFunction'的格式,指定一系列的事件绑定:

// A sample view
var TodoView = Backbone.View.extend({
  tagName:  'li',

  // with an events hash containing DOM events
  // specific to an item:
  events: {
    'click .toggle': 'toggleCompleted',
    'dblclick label': 'edit',
    'click .destroy': 'clear',
    'blur .edit': 'close'
  },

selector 只在 el 的 dom 里查找

Collections

是一组 model. 可以这样来理解, 和 python 来比: * model = dict * collections = list

可以用addremove来增删,没什么太多可说的

var Todo = Backbone.Model.extend({
  defaults: {
    title: '',
    completed: false
  }
});

var TodosCollection = Backbone.Collection.extend({
  model: Todo,
});

var a = new Todo({ title: 'Go to Jamaica.'}),
    b = new Todo({ title: 'Go to China.'}),
    c = new Todo({ title: 'Go to Disneyland.'});

var todos = new TodosCollection(![pic](a,b));
console.log("Collection size: " + todos.length);
// Logs: Collection size: 2

todos.add(c);
console.log("Collection size: " + todos.length);
// Logs: Collection size: 3

todos.remove(![pic](a,b));
console.log("Collection size: " + todos.length);
// Logs: Collection size: 1

todos.remove(c);
console.log("Collection size: " + todos.length);
// Logs: Collection size: 0

也可以转 json

var items = new Backbone.Collection;
items.add([{ id : 1, name: "Dog" , age: 3}, { id : 2, name: "cat" , age: 2}]);
items.add([{ id : 1, name: "Bear" }], {merge: true });
items.add([{ id : 2, name: "lion" }]); // merge: false

console.log(JSON.stringify(items.toJSON()));
// ![pic]({"id":1,"name":"Bear","age":3},{"id":2,"name":"cat","age":2})

用id来回收 model

注意必须要有id字段

var myTodo = new Todo({title:'Read the whole book', id: 2});

// pass array of models on collection instantiation
var todos = new TodosCollection(![pic](myTodo));

var todo2 = todos.get(2);

// Models, as objects, are passed by reference
console.log(todo2 === myTodo); // true

events

collections 可以绑定 add,remove 方法.

var TodosCollection = new Backbone.Collection();

TodosCollection.on("add", function(todo) {
  console.log("I should " + todo.get("title") + ". Have I done it before? "  + (todo.get("completed") ? 'Yeah!': 'No.' ));
});

TodosCollection.add([
  { title: 'go to Jamaica', completed: false },
  { title: 'go to China', completed: false },
  { title: 'go to Disneyland', completed: true }
]);

// The above logs:
// I should go to Jamaica. Have I done it before? No.
// I should go to China. Have I done it before? No.
// I should go to Disneyland. Have I done it before? Yeah!

函数传入的当前在操作的这个 model

也可以直接在collection绑定 change 方法,取出的任何一个model改变都能触发.

var TodosCollection = new Backbone.Collection();

// log a message if a model in the collection changes
TodosCollection.on("change:title", function(model) {
    console.log("Changed my mind! I should " + model.get('title'));
});

TodosCollection.add([
  { title: 'go to Jamaica.', completed: false, id: 3 },
]);

var myTodo = TodosCollection.get(3);

myTodo.set('title', 'go fishing');
// Logs: Changed my mind! I should go fishing

once 也可以用,不多说了.

批量操作

set

set 可以给一组数据给 collections,根据 id 来自行进行合并

var TodosCollection = new Backbone.Collection();

TodosCollection.add([
    { id: 1, title: 'go to Jamaica.', completed: false },
    { id: 2, title: 'go to China.', completed: false },
    { id: 3, title: 'go to Disneyland.', completed: true }
]);

// we can listen for add/change/remove events
TodosCollection.on("add", function(model) {
  console.log("Added " + model.get('title'));
});

TodosCollection.on("remove", function(model) {
  console.log("Removed " + model.get('title'));
});

TodosCollection.on("change:completed", function(model) {
  console.log("Completed " + model.get('title'));
});

TodosCollection.set([
    { id: 1, title: 'go to Jamaica.', completed: true },
    { id: 2, title: 'go to China.', completed: false },
    { id: 4, title: 'go to Disney World.', completed: false }
]);

// Above logs:
// Removed go to Disneyland.
// Completed go to Jamaica.
// Added go to Disney World.

reset

reset 则是直接替換

var TodosCollection = new Backbone.Collection();

// we can listen for reset events
TodosCollection.on("reset", function() {
  console.log("Collection reset.");
});

TodosCollection.add([
  { title: 'go to Jamaica.', completed: false },
  { title: 'go to China.', completed: false },
  { title: 'go to Disneyland.', completed: true }
]);

console.log('Collection size: ' + TodosCollection.length); // Collection size: 3

TodosCollection.reset([
  { title: 'go to Cuba.', completed: false }
]);
// Above logs 'Collection reset.'

console.log('Collection size: ' + TodosCollection.length); // Collection size: 1

其它內置方法

forEach,sortBy…..

chain

chain,pluck

RESTful Persistence

fetch/GET

用fetch以http get 方法取数

var Todo = Backbone.Model.extend({
  defaults: {
    title: '',
    completed: false
  }
});

var TodosCollection = Backbone.Collection.extend({
  model: Todo,
  url: '/todos'
});

var todos = new TodosCollection();
todos.fetch(); // sends HTTP GET to /todos
save/PUT(POST)

建立或更新

var Todo = Backbone.Model.extend({
  defaults: {
    title: '',
    completed: false
  }
});

var TodosCollection = Backbone.Collection.extend({
  model: Todo,
  url: '/todos'
});

var todos = new TodosCollection();
todos.fetch();

var todo2 = todos.get(2);
todo2.set('title', 'go fishing');
todo2.save(); // sends HTTP PUT to /todos/2

todos.create({title: 'Try out code samples'}); // sends HTTP POST to /todos and adds to collection
patch

只提交修改了的

// Save partial using PATCH
model.clear().set({id: 1, a: 1, b: 2, c: 3, d: 4});
model.save();
model.save({b: 2, d: 4}, {patch: true});
console.log(this.syncArgs.method);
// 'patch'
remove/DELETE

删除

var Todo = Backbone.Model.extend({
  defaults: {
    title: '',
    completed: false
  }
});

var TodosCollection = Backbone.Collection.extend({
  model: Todo,
  url: '/todos'
});

var todos = new TodosCollection();
todos.fetch();

var todo2 = todos.get(2);
todo2.destroy(); // sends HTTP DELETE to /todos/2 and removes from collection

comments powered by Disqus