zoukankan      html  css  js  c++  java
  • Backbone学习记录(1)

    去年买的《基于MVC的javascript Web富应用开发》,拖到现在还没看完,作者介绍了三个MVC框架,Spine ,backbone和javascriptMVC。1和2在国内的流行度,不高,我就只打算学backbone了。

    backbone依赖于underscore.js,所以在引入的时候需要先引underscore -_-#
    =>  Uncaught TypeError: Cannot call method 'each' of undefined

    Backbone的模块

    1)Events 事件驱动方法
    2)Model 数据模型
    3)Collection 模型集合器
    4)Router 路由(hash)
    5) History 开启历史管理
    6) Sync 同步服务器方式
    7) View 视图(事件行为与渲染页面)

    Events模块可以混合到任何模块中。使对象可以绑定和触发自定义事件。

    _.extend(Model.prototype, Events, {});
    _.extend(Collection.prototype, Events, {});
    _.extend(View.prototype, Events, {});
    _.extend(Router.prototype, Events, {});

    Model与Collection的关系:Collection是Model的集合,对单独的模型集合在一起然后进行整体操作。

    backbone的控制器并没有单独分离出来,它与渲染视图一起混杂在View中。


    Backbone对象

    console.log(Backbone);
    
    /*{
        $: function ( selector, context ) {},
        Collection: function (models, options) {},
        Events: Object,
        History: function () {},
        Model: function (attributes, options) {},
        Router: function (options) {},
        VERSION: "1.1.2",
        View: function (options) {},
        ajax: function () {},
        bind: function (name, callback, context) {},
        emulateHTTP: false,
        emulateJSON: false,
        history: Backbone.History,
        listenTo: function (obj, name, callback) {},
        listenToOnce: function (obj, name, callback) {},
        noConflict: function () {},
        off: function (name, callback, context) {},
        on: function (name, callback, context) {},
        once: function (name, callback, context) {},
        stopListening: function (obj, name, callback) {},
        sync: function (method, model, options) {},
        trigger: function (name) {},
        unbind: function (name, callback, context) {},
        __proto__: Object
    }*/


    Model

    看一下Backbone的Model构造器

      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);
      };

    options用第2种写法的原因是其性能更好,如果options存在,就可避免一次赋值的操作

    options=options||{};//1
    options|(options={});//2

    cid属性不知道是干嘛的,为什么要把attributes属性留出来?以及中间那一大堆都在干嘛,最后是调用了initialize方法做初始化工作?

    创建一个Model:(好吧,写错了,User和User1都应该用小写开头- -)

    var User=new Backbone.Model();

    var User1=new Backbone.Model({'name':'susan'});

    Model.extend()方法

    keys(Backbone.Model)
    //["extend"]
    Model有一个静态方法extend:没看过underscore,源码以后再看 ~~~~(>_<)~~~~ 
    总之,第一个参数对象的属性都被传到了extend生产的构造器的原型上,第二个参数对象的属性都成了extend生成的构造器的静态属性
      var extend = function(protoProps, staticProps) {
        var parent = this;
        var child;
    
        // The constructor function for the new subclass is either defined by you
        // (the "constructor" property in your `extend` definition), or defaulted
        // by us to simply call the parent's constructor.
        if (protoProps && _.has(protoProps, 'constructor')) {
          child = protoProps.constructor;
        } else {
          child = function(){ return parent.apply(this, arguments); };
        }
    
        // Add static properties to the constructor function, if supplied.
        _.extend(child, parent, staticProps);
    
        // Set the prototype chain to inherit from `parent`, without calling
        // `parent`'s constructor function.
        var Surrogate = function(){ this.constructor = child; };
        Surrogate.prototype = parent.prototype;
        child.prototype = new Surrogate;
    
        // Add prototype properties (instance properties) to the subclass,
        // if supplied.
        if (protoProps) _.extend(child.prototype, protoProps);
    
        // Set a convenience property in case the parent's prototype is needed
        // later.
        child.__super__ = parent.prototype;
    
        return child;
      };
    var User1=Backbone.Model.extend({});
    var User2=Backbone.Model.extend({'initalize':function(){console.log('init ing')}});
    var user1=new User1();
    var user2=new User2();

    cid似乎是实例的标志。对比user1和user2,可知,Backbone.Model.extend构造器传入的第一个参数(对象)属性添加到了原型链上。



    Backbone.Model.extend生成的User2构造器,比如这里,在实例化User2的时候传入{'name':'susan'},这些键值对最后被保存在了实例的attributes属性中。

    var User4=Backbone.Model.extend({'initalize':function(){console.log('init ing')}},{'checkFn':function(){console.log("check fn ing")}});
    keys(User4);
    //["extend", "checkFn", "__super__"]

     这里可以看到,checkFn确实是作为了User4的静态属性。


    set 和 get方法

    var User1=Backbone.Model.extend({});
    var user1=new User1({'name':'susan'});
    user1.get('name');
    //"susan"

    从这里可以看到 new User1()的时候传入一个对象参数,等同于user1.set()方法 ?

    set的两种用法 : set(name,value) 与 set({name:value})

    user1.set('name','lily');
    user1.get('name');
    //lily
    user1.set({'name':'lucy','age':'25'});
    user1.get('name');//lucy
    user1.get('age');//25
  • 相关阅读:
    MFC中小笔记(四)
    MFC中小笔记(三)
    MFC中小笔记
    关于小蜘蛛诞生的坎坎坷坷
    Win32Api程序设计 常用域改变(设定)窗口位置、大小的api
    Win32Api程序设计 注册窗口类
    TCP segment of a reassembled PDU【转】
    计算机网络复习 -- 概念梳理
    指针(pointer) -- (上)
    原来我连真正的调试都不会,每次都是靠编译器(⊙﹏⊙)b
  • 原文地址:https://www.cnblogs.com/qianlegeqian/p/3929743.html
Copyright © 2011-2022 走看看