说说backbone.js

简介:

backbone是一个非常优秀的前端MVC框架,灵活度非常高,浏览器兼容支持的也很好,跟angularjs相比,它显得非常轻量,相关的中文API文档,可以点击这里,然后backbone深度依赖underscore,详情点击这里


今天谈谈我对backbone的一些理解.

关于Event

事件在框架里起着关键的作用,而且事件一般是独立模块,backbone的模型,集合,视图默认都会继承事件,下面简单的说下事件的用法

on 定义一个事件

var obj = {
    name: 'feenan'
};
// 使自定义对象拥有事件方法
_.extend(obj, Backbone.Event);

obj.on('go', function(){
    console.log(this.name);
});

obj.trigger('go');

trigger会触发事件,支持传递回调参数以及回调函数的上下文,在backbone里定义事件也可以指定到单个属性,比如下面Model里定义的change:xuwm.

下面说说在backbone里事件的几个特点

  • 模型的任务事件触发最后都会触发all事件,除非传递silent:true
  • 模型的任何属性改变事件都后都会触发change事件,除非传递silent:true
  • 对集合元素的添加删除都会触发元素集合的all事件,除非传递silent:true

关于Model

模型在一个框架里面一般用来定义基本数据以及数据相关的操作,在backbone里一般可以这样来定义Model

var Todo = Backbone.Model.extend({
    initialize: function(){
        this.on('invalid', function(){
            console.log('不能通过验证!');
        });
        this.on('change:xuwm', function(){
            console.log('change xuwm event...');
        });
        this.on('add', function(){
            log('被添加到集合中....');
        })
        this.on('change', function(){
            log('invoke change event!');
        });
        console.log('模型初始化...');
    },
    validate: function(attrs){
        if(attrs.xuwm == 'feenan'){
            return true;
        }else{
            return false;
        }
    },
    defaults: function(){
        return {
            name: 'xuwm',
            age: 20
        }
    }
});

extend方法主要是在Model的基础上扩展一些自定义的属性与方法,来看看Model本身支持的一些让开发者重载的方法或者属性

initialize 当模型被实例化完成时,会触发此方法,一般可以在这里定义事件

defaults 定义模型的默认值

validate 定义模型属性验证方法,在这里可以对将要设置的属性进行验证,返回true则不修改属性,返回false则修改属性

下面我们来使用上面定义的模型

var todo = new Todo;

todo.set({xuwm: 'feenan'});

这里要强调一下,验证属性不会发生在new模型的时候,只会发生在实例之后,因为定义验证事件是在实例生成之后绑定的.比如上面例子里的set方法,这是模型的一个核心方法.

关于Collection

集合是专门用来管理模型的,然后提供了数组相关的方法,跟underscore里的方法相似,因为底层都是调用它的方法.下面是一个定义集合的例子

var TodoList = Backbone.Collection.extend({
    model: Todo,
    localStorage: new Backbone.LocalStorage("todos-backbone"),
    rest: function(){
        return this.where({done: false});
    },
    done: function(){
        return this.where({done: true});
    }
});

集合一般用来跟后台数据相关联,比如增删改查,上面例子里的后端数据用的是本地localStorage,假如不定义localStorage属性,则后台数据请求默认用的是Backbone.ajax来处理,这里用到了一个backbone的一个本地存储插件backbone.localStorage.js

model属性代表此集合关联哪个类型的模型

下面说说集合常用的方法

create 创建一个模型并保存到后台

var todos = new TodoList;
todos.create({xuwm: 'tina'});

create 方法最后调用模型的save方法提交到后台,此处就是往本地存储里添加信息

fetch 从后台拉取数据集合

todos.fetch();

fetch 方法会调用后台服务里的read方法,后台服务在backbone里指Backbone.sync模块,最终调用set方法来依次添加数据到模型里,并绑定模型的all事件跟集合进行关联,保证模型的修改会提醒集合的更新.

以下是添加模型时跟集合进行关联的源码js // Internal method to create a model's ties to a collection. _addReference: function(model, options) { this._byId[model.cid] = model; if (model.id != null) this._byId[model.id] = model; if (!model.collection) model.collection = this; model.on('all', this._onModelEvent, this); }, // Internal method called every time a model in the set fires an event. // Sets need to update their indexes when models change ids. All other // events simply proxy through. "add" and "remove" events that originate // in other collections are ignored. _onModelEvent: function(event, model, collection, options) { if ((event === 'add' || event === 'remove') && collection !== this) return; if (event === 'destroy') this.remove(model, options); if (model && event === 'change:' + model.idAttribute) { delete this._byId[model.previous(model.idAttribute)]; if (model.id != null) this._byId[model.id] = model; } this.trigger.apply(this, arguments); }

where 根据参数查找出相关集合列表

todos.where({xuwm: 'feenan'});

类似的数组操作方法有很多,基本上思想跟underscore里的collection差不多,更多的方法可以参考underscore.

关于View

视图在backbone里起承上启下的作用,基本上在backbone里,集合和模型都在这里进行活动,下面给出一个定义视图的例子

var TodoView = Backbone.View.extend({
    tagName: 'li',
    template: _.template($('#item-template').html()),
    events: {
        'change .toggle': 'toggleOne',
        'click .destroy': 'destroyOne'
    },
    initialize: function(){
        this.listenTo(this.model, 'change', this.render);
        this.listenTo(this.model, 'destroy', this.remove);
    },
    render: function(){
        this.$el.html(this.template(this.model.toJSON()));
        this.$el.toggleClass('done', this.model.get('done'));
        this.input = this.$el;
        return this;
    },
    toggleOne: function(){
        this.model.toggle();
    },
    destroyOne: function(){
        if(window.confirm('是否删除此任务?')){
            this.model.destroy();
        }
    }
});

视图首先要关联页面上一个元素,通过id,class,tag方式来绑定,然后绑定相关的dom事件,在事件里对模型或者集合进行处理

这里说下视图里比较常用的几个属性

  • initialize 初始化方法,定义一些对横型或者集合事件的绑定
  • events 以一个简单的方式来统一定义视图里事件通过委托方式
  • tagName/el 通过id,class,tag 来定义视图对应的页面元素

关于 Router

Routerbackbone里比较重要,支持html5的pushstate或者onhashchange的方式来管理路由的改变,下面是定义一个路由的例子

var Router = Backbone.Router.extend({
    routes: {
        '': 'home',
        'feenan': 'feenan'
    },
    home: function(){
        todos = new TodoList;
        var app = new AppView;
    },
    feenan: function(){
        var feenanView = new FeenanView;
    }
});

关于路由有几个常用的方法先介绍下

  • routes 跟视图里的events有点类似,也是以key,value的形式来定义多个路由,key为hash值,value为路由回调函数
  • navigate 在代码里指定要跳到哪个路由,传递{trigger: true}代表跳转时会执行路由回调函数

下面是使用路由的代码

var router = new Router;

Backbone.history.start();

Backbone.History是路由的核心模块,start方法是启动路由的关键方法,这里关键是算是浏览器的兼容以及初始路由事件的地方

关于 Sync

sync名为同步,实为同步后台数据,其实就是一个访问后台数据的统一调用方式,提供有增删改查的方法

默认会调用Backbone.ajax来访问后台接口,上面例子里的调用后台是用的本地存储的插件backbone.localStorage.js,调用后台接口的地方都在backbone内部发生

总结

本文只是对backbone的一个简单流程的梳理,更多详细的内容请查看backbone的源码.


目录
相关文章
|
3月前
|
算法 JavaScript
|
10月前
|
JavaScript
|
10月前
|
JavaScript
|
10月前
|
JavaScript API
|
前端开发 JavaScript SEO
Hammer.js分析(四)——recognizer.js
不同识别器会使用不同逻辑,根据从相关Input类获取到的事件对象和事件,实现自定义的触屏事件,例如tap、pinch等。
Hammer.js分析(四)——recognizer.js
|
存储 JavaScript 前端开发
|
JavaScript 前端开发