• 【转】Backbone.js学习笔记(二)细说MVC


    文章转自:

    http://segmentfault.com/a/1190000002666658

    对于初学backbone.js的同学可以先参考我这篇文章:Backbone.js学习笔记(一)

    Backbone源码结构

    图片描述

       1:  (function() {
    
       2:      Backbone.Events        // 自定义事件
    
       3:      Backbone.Model        // 模型构造函数和原型扩展
    
       4:      Backbone.Collection    // 集合构造函数和原型扩展
    
       5:      Backbone.Router        // 路由配置器构造函数和原型扩展
    
       6:      Backbone.History        // 路由器构造函数和原型扩展
    
       7:      Backbone.View            // 视图构造函数和原型扩展
    
       8:      Backbone.sync            // 异步请求工具方法
    
       9:      var extend = function (protoProps, classProps) { ... } // 自扩展函数
    
      10:      Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = extend; // 自扩展方法
    
      11:  }).call(this);
    

    JS MVC职责划分

    M 模型

    业务模型:业务逻辑、流程、状态、规则
    (核心)数据模型:业务数据、数据校验、增删改查(AJAX)
    

    V 视图

    (核心)视图:定义、管理、配置
    模板:定义、配置、管理
    组件:定义、配置、管理
    (核心)用户事件配置、管理
    用户输入校验、配置、管理
    

    C 控制器/分发器

    (核心)事件分发、模型分发、视图分发
    不做数据处理、业务处理,即业务无关
    扩展:权限控制、异常处理等
    C是JSMVC框架的核心,实现集中式配置和管理,可以有多个控制器
    

    工具库

    主要是异步请求、DOM操作,可以依赖于jQuery等
    

    来源:http://www.cnblogs.com/nuysoft/archive/2012/03/14/2395272.html

    Model指的是一条一条的数据,而集合Collection指的是对Model中的多条数据进行管理。

    模型 Model

    我们用Backbone.Model表示应用中所有数据,models中的数据可以创建、校验、销毁和保存到服务端。

    对象赋值的方法

    1、直接定义,设置默认值

     Trigkit = Backbone.Model.extend({
                 initialize : function () {
                     alert('hi!');
                 },
                 defaults:{
                     age : '22',
                     profession : 'coder'
                 }
             });
            var coder = new Trigkit;
            alert(coder.get('age'));//22
    

    2、 赋值时定义

    <script type="text/javascript">
         Trigkit = Backbone.Model.extend({
             initialize : function () {
                 alert('hi!');
             }
         });
         var t = new Trigkit;
         t.set({name :'huang',age : '10'});
         alert(t.get('name'));
    </script>        
    

    对象中的方法

    <script type="text/javascript" src="Underscore.js"></script>
    <script type="text/javascript" src="backbone-1.1.2.js"></script>
    <script type="text/javascript">
            var Trigkit4 = Backbone.Model.extend({
                initialize : function () {
                    alert("hello world!");
                },
                defaults : {
                    name : 'zhangsan',
                    age : 21
                },
                aboutMe: function () {
                    return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁';
                }
            });
            var t = new Trigkit4;
            alert(t.aboutMe());
        </script>
    

    当模型实例化时,他的initialize方法可以接受任意实例参数,其工作原理是backbone模型本身就是构造函数,所以可以使用new生成实例:

    var User = Backbone.Model.extend({
        initialize: function (name) {
            this.set({name: name});
        }
    });
    var user = new User('trigkit4');
    alert(user.get('name'), 'trigkit4');//trigkit4
    

    看下backbone的源码:

    var Model = Backbone.Model = function(attributes, options) {
        var attrs = attributes || {};
        options || (options = {});
        this.cid = _.uniqueId('c');
        this.attributes = {};
        if (options.collection) this.collection = options.collection;
        if (options.parse) attrs = this.parse(attrs, options) || {};
        attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
        this.set(attrs, options);
        this.changed = {};
        this.initialize.apply(this, arguments);
      };
    
     initialize: function(){},//initialize是默认的空函数
    

    Model 的事件绑定

    为了能及时更新view,我们需要通过事件绑定机制来处理和响应用户事件:

        <script type="text/javascript">
            var Task = Backbone.Model.extend({
                initialize: function () {
                    this.on("change:name", function (model) {
                        alert("my name is : " + model.get("name"));
                    });
                }
            });
    
            var task = new Task({ name:"oldname", state:"working"});
            task.set({name:"trigkit"});
    //        object.on(event, callback, [context])
        </script>
    </head>
    

    关于事件绑定,有on,off,trigger,once,listenTo,stopListening,listenToOnce等方法,具体参照:http://documentcloud.github.io/backbone/#Events

    图片描述

    集合 Collection

    Backbone.Collection就是一个Model对象的有序集合。因为Model是一条数据记录,也就是说,Collection相当于是一个数据集。具有增加元素,删除元素,获取长度,排序,比较等一系列工具方法,说白了就是一个保存models的集合类。

    <script type="text/javascript">
        var Book = Backbone.Model.extend({
            defaults : {
                title:'default'
            },
    
            initialize: function(){
    
                 alert('hello backbone!');//弹出3次
            }
        });
    
        BookShelf = Backbone.Collection.extend({
    
            model : Book
    
        });
    
        var book1 = new Book({title : 'book1'});
    
        var book2 = new Book({title : 'book2'});
    
        var book3 = new Book({title : 'book3'});
    
        //var bookShelf = new BookShelf([book1, book2, book3]); //注意这里面是数组,或者使用add
    
        var bookShelf = new BookShelf;
    
        bookShelf.add(book1);
        bookShelf.add(book2);
        bookShelf.add(book3);
        bookShelf.remove(book3);
    
        //基于underscore这个js库,还可以使用each的方法获取collection中的数据
        bookShelf.each(function(book){
    
            alert(book.get('title'));
    
        });
    </script>
    

    collection.model覆盖此属性来指定集合中包含的模型类。可以传入原始属性对象(和数组)来 addcreate,和reset,传入的属性会被自动转换为适合的模型类型。
    图片描述

    视图 View

    Backbone.View中可以绑定dom元素和客户端事件。页面中的html就是通过viewsrender方法渲染出来的,当新建一个view的时候通过要传进一个model作为数据

    view.$el:一个视图元素的缓存jQuery对象。 一个简单的引用,而不是重新包装的DOM元素。 
    

    一个简单的View:

    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script type="text/javascript" src="jquery-1.9.1.min.js"></script>
        <script type="text/javascript" src="Underscore.js"></script>
        <script type="text/javascript" src="backbone-1.1.2.js"></script>
        <script type="text/javascript">
    
                var TestView = Backbone.View.extend({ //创建一个view,其实就是一个HTML的DOM节点
                    initialize: function() {
                        this.render();
                    },
                    render: function() {  // 渲染方法
                        this.$el.html('Hello World');  //this.el就是HTML节点,通过jQuery的html方法填充内容
                        return this;
                    }
                });
    
                $(function () {
                    var test = new TestView({el: $('#body')});// 以目标节点为el参数,创建一个view的实例,render函数将会被自动调用并将渲染结果填充到el中
                    //test.render(); // 如果没在 initialize 里调用 render 的话,就需要在这里调用一次
                });
        </script>
    </head>
    <body>
    <div id="body"></div>
    </body>
    

    elview.el所有的视图都拥有一个 DOM 元素(el 属性),即使该元素仍未插入页面中去。 视图可以在任何时候渲染,然后一次性插入 DOM 中去,这样能尽量减少 reflows 和 repaints 从而获得高性能的 UI 渲染。 this.el 可以从视图的 tagNameclassNameid 和 attributes 创建,如果都未指定,el 会是一个空 div。 --官网

    图片描述

    扩展方法 extend

    模型、集合、视图、路由器都有一个extend方法,用于扩展原型属性和静态属性,创建自定义的模型、集合、视图、路由器类。

    Backbone.Model.extend

    Backbone.Model.extend(properties, [classProperties])
    

    要创建自己的 Model 类,你可以扩展 Backbone.Model 并提供实例 properties(属性) , 以及可选的可以直接注册到构造函数的classProperties(类属性)。

    Backbone.View.extend

    Backbone.View.extend(properties, [classProperties])
    

    开始创建自定义的视图类。 通常我们需要重载 render 函数,声明 events, 以及通过 tagNameclassName, 或 id为视图指定根元素。 Backbone.View通过绑定视图的 render 函数到模型的 "change" 事件 — 模型数据会即时的显示在 UI 中。

    Backbone.Collection.extend

    Backbone.Collection.extend(properties, [classProperties])
    

    通过扩展 Backbone.Collection 创建一个 Collection 类。实例属性参数 properties 以及 类属性参数classProperties 会被直接注册到集合的构造函数。

    Backbone.Router.extend

    Backbone.Router.extend(properties, [classProperties])
    

    开始创建一个自定义的路由类。当匹配了 URL 片段便执行定义的动作,并可以通过 routes 定义路由动作键值对。

    Router与controller

    controllerBackbone 0.5以前的叫法,现在改名叫Router了。

    Backbone.Router 为客户端路由提供了许多方法,并能连接到指定的动作(actions)和事件(events)。
    页面加载期间,当应用已经创建了所有的路由,需要调用 Backbone.history.start()

    查看下面示例:

    <script type="text/javascript">
            var AppRouter = Backbone.Router.extend({
                routes: {
                    "index" : "index",
                    "task/:id": "task",
                    "*acts": "tasklist"
                },
                index: function() {
                    alert("index");
                },
                tasklist: function(action) {
                    alert(action);
                },
                task: function(id) {
                    alert(id);
                }
            });
    
            var app = new AppRouter;
            Backbone.history.start();
        </script>
    

    在浏览器里打开页面后,在urlhtml后面依次加上:

    #/index
    #/task/1
    #/test/xxxx
    

    将分别弹出出:index, 1, test/xxxx

    这就是Router的功能。

    backbone github官网:http://documentcloud.github.io/backbone/

  • 相关阅读:
    JNI内存使用问题(转载)
    typearray和obtainStyledAttribute的作用
    handler looper代码总结(原创)精品推荐
    Appium和Robotium在文字输入上的区别
    老李分享:robotium3.6与4.0 later 的区别 2
    老李分享:robotium3.6与4.0 later 的区别 1
    老李分享:robotium常用API 2
    老李分享:robotium常用API 1
    老李分享:Android -自动化埋点 3
    老李分享:Android -自动化埋点 2
  • 原文地址:https://www.cnblogs.com/liubei/p/Backbone_02.html
Copyright © 2020-2023  润新知