backbone学习进阶—

深入理解Backbone:事件绑定与数据操作
本文详述了Backbone.js的学习过程,涵盖了关键知识点,包括事件绑定、模型数据操作、集合操作和与服务器的交互。重点讨论了模型的初始化、验证机制、数据清除、事件监听与触发、模型与集合的添加、删除和排序,以及如何与服务器进行数据同步。同时,讲解了视图中元素事件的动态绑定和取消。

早就知道backbone有一些好处,今天开始系统的学习一下backbone了,然后自己在这里贴一些傻逼的不行的代码片段。

  • 代码一
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<script src="jquery-2.1.3.min.js"></script>
<script src="underscore-min.js"></script>
<script src="backbone-min.js"></script>
<body>

<div id="search_con">
    <input  type="button"  id="search_input" value="hahaha">
    <div id="div2"></div>
</div>
<script>
    (function ($) {
        AppView=Backbone.View.extend({
            el: $("body"),
            initialize:function(){
                this.render();
            },
            render:function(){
                var template="我就是哈哈了一下";
                $("#div2").html(template);
            },
            events:{
                "click #search_input":"checkIn" //事件绑定,绑定Dom中id为check的元素
            },
            checkIn: function(event){
                alert("search for");
//            var world_name = prompt("请问,您是哪星人?");
            }
        });

        var appview= new AppView();
    })(jQuery);
</script>
</body>
</html>

有几个点第一次没有注意:
1. backbone一定要写在 (function ($) {...})(jQuery);里面,这个自己一开始就没有记住。
2.jquery的语法要记熟,说实在的明天还应该看看jquery,看看一些怎么写的比如$("#div2").html(template);这句话自己一开始就是因为语法问题写错了。
3. 注意el: $("body") 怎么写,以及可以写在不同的位置

  • 通过backbone绑定多个事件并且通过history获取历史信息等。
var person = Backbone.Model.extend({ defaults: {
name: "", sex: " 女 ", age: 32, score: 120
} });
var man = new person();
man.on("change:score change:age", function (model, value) {
var oldage = model.previous("age");
var newage = model.get("age");
if (oldage != newage) {
} console.log("age 原值 :" + oldage + ", 新值 :" + newage);
var oldscore = model.previous("score"); var newscore = model.get("score");
if (oldscore != newscore) {
console.log("score 原值 :" + oldscore + ", 新值 :" + newscore);
}
});
man.set("age", 36); man.set("score", 200);
  • 通过once保证事件只被触发一次
var person = Backbone.Model.extend({ defaults: {
name: "", sex: " 女 ", age: 32, score: 120
}); }
var man = new person();
var intNum = 0; man.once("change", function () {
intNum++;
}); console.log("事件触发的次数为"+intNum);
man.set("age", 36); man.set("age", 37);
  • 手动触发一个事件
var person = Backbone.Model.extend({ defaults: {
name: "", sex: " 女 ", age: 32, score: 120
}); }
var man = new person(); man.on("change_age_sex", function () {
}); console.log("您手动触发了一个自定义事件");
man.on("change:age", function (model, value) { if (value != undefined)
elseconsole.log(" 您修改后的年龄为 " + value);
console.log(" 您手动触发了一个年龄修改事件 "); })
man.trigger("change_age_sex"); man.trigger("change:age"); man.set("age", 37);
  • 决定移除一个事件的代码
var person = Backbone.Model.extend({ defaults: {
name: "", sex: " 女 ", age: 32, score: 120
}); }
var man = new person();
var m=0, n=0;
var callback_a = function () {
m++;
} console.log(" 您执行 a 事件的次数为 " + m);
var callback_b = function () { n++;
} console.log(" 您执行 b 事件的次数为 " + n);
man.on("event_a", callback_a); man.on("event_b", callback_b); man.off("event_a"); man.trigger('event_a event_b'); man.off("event_a event_b"); man.trigger('event_a event_b');

//下一个是移除全部的事件
var person = Backbone.Model.extend({ defaults: {
name: "", sex: " 女 ", age: 32, score: 120
}); }
var man = new person();
var m=0, n=0;
var callback_a = function () {
m++;
} console.log(" 您执行 a 事件的次数为 " + m);
var callback_b = function () { n++;
} console.log(" 您执行 b 事件的次数为 " + n);
man.on("event_a", callback_a); man.on("event_b", callback_b); man.off();
man.trigger('event_a event_b');
  • 当然backbone也可以用监听事件
var person = Backbone.Model.extend({ defaults: {
name: "", sex: " 女 ", age: 32, score: 120
}); }
var man = new person();
var obj = _.extend({}, Backbone.Events); obj.listenTo(man, "change:age", function (model, value) {
var oldage = model.previous("age"); var newage = model.get("age");
if (oldage != newage) {
console.log("age 原值 :" + oldage + ", 新值 :" + newage); }); }
man.set("age", 37);
  • 监听一次事件
var person = Backbone.Model.extend({ defaults: {
name: "", sex: " 女 ", age: 32, score: 120
}); }
var man = new person();
var obj = _.extend({}, Backbone.Events);
var intNum = 0;
obj.listenToOnce(man, "change:age", function () {
intNum++;
}); console.log("事件触发的次数为"+intNum);
man.set("age", 37); man.set("age", 38);
  • 停止监听事件
obj.stopListening(man, "change:name change:age");
  • all事件
Obj.on("all",function);
  • model每重新初始化一个实例,就会执行一次initialize函数。
var student = Backbone.Model.extend({
initialize: function () {
intNum++;
console.log("您构建了" + intNum + "个对象");
}
});
var intNum = 0;
var stuA = new student();
var stuB = new student();
  • 重置模型中的默认值。
Obj.set(attrName, attrValue)
//第二种方法:
Obj.set({attrName1:attrValue1,attrName2:attrValue2,...})
  • 获取模型中的值
Obj.get(attrName)
Obj.escape(attrName)
//后者更安全因为可以实例化防攻击。
  • 数据验证机制
    1)添加validate方法。在该方法中确定数据校验的标准,即数据在什么情况下,认为它是不正确的,如果不正确,返回提示信息。
    2)绑定对象invalid事件。数据验证失败后会触发该事件,在该事件中,通过返回的参数可以接收validate方法中传来的提示信息。
    3)使用set方法添加/修改属性时,必须将validate属性值设置为true,用于通知Backbone框架此次的数据操作是需要进行验证的。
 var student = Backbone.Model.extend({
        initialize: function () {
            this.on('invalid', function (model, error) {
                console.log(error)
            });
        },
        validate: function (attrs) {
            if (!_.isString(attrs.Name)) return '姓名必须是字符!'
            if (!_.isNumber(attrs.Score)) return '分数必须是数字!'
        },
        defaults: {
            Code: "10001",
            Name: "张三",
            Score: 100
        }
    });
  var stuE = new student();
  stuE.set({
        Code: "10105",
        Name: 12345,
        Score: 600
    }, { "validate": true });
  console.log(stuE.toJSON());

在Backbone中调用set方法时,不将validate属性值设置为true,本次set方法将不会进行数据验证。此外,在调用set方法时,还可以将silent属性值设置为true,表示静默式修改数据,即在修改数据时,不触发任何事件。这其中也包括绑定的属性事件,当然也不会触发数据验证事件,而直接更新数据。

var stuE = new student();
stuE.set({
Code: "10105",
Name: 12345,
Score: "600"
}, { "silent": true });
  • 数据清除
Obj.unset(attrName)
后者为清除对象中的全部数据,该方法没有参数,调用的格式如下。
Obj.clear()
  • 输出属性和值
    以下两种方式输出属性和值:
//直接输出attributes对象
console.log(stuE.attributes);
//遍历后输出attributes对象中的每项属性和值
var attrs = stuE.attributes;
for (var i in attrs) {
console.log(i + ":" + stuE.attributes[i]);
}
  • 返回对象在修改前的属性值
Obj.previous(attrName)
第二种方法返回一个对象,包含上一个状态的全部数据,该方法没有参数,调用的格式如下。
Obj.previousAttributes()
  • save 方法发送数据
    先设置浏览器请求服务器的地址,就可以通过save方法保存数据了。
 var student = Backbone.Model.extend({
        initialize: function () {
//构造函数
        },
        url:"/Ch4/api/save.php",
        defaults: {
            Code: "10001",
            Name: "张三",
            Score: 100
        }
    });
    var stuE = new student();
    stuE.set({
        Code: "10107",
        Name: "陶国荣",
        Score: 750
    });
    stuE.save();

//也可以接收返回值
stuE.save(null, {
success: function (model, response) {
console.log(response.code);
}
  • 将wait属性设置为true,如果没有通过验证的话是不会发送数据的。
    var student = Backbone.Model.extend({
        initialize: function () {
//构造函数
        },
        url:"/Ch4/api/save2.php"
        defaults: {
            Code: "10001",
            Name: "张三",
            Score: 100
        }
    });
    var stuE = new student();
    stuE.save({
        Code: "10107",
        Name: "陶国荣",
        Score: 750
    }, { success: function (model, response) {
        console.log(response);
    }, wait: true
    });
    console.log(stuE.toJSON());
  • 从服务端获取数据
var student = Backbone.Model.extend({
        initialize: function () {
//构造函数
        },
        url: "/Ch4/api/fetch.php"
    });
    var stuE = new student();
    stuE.fetch({
        success: function (model, response) {
            console.log(stuE.toJSON());
        },
        error: function (err) {
            console.log("err");
        }
    });
  • 从服务端删除数据
var student = Backbone.Model.extend({
        initialize: function () {
//构造函数
            this.on('destroy', function () {
                console.log('正在调用destroy方法');
            });
        },
        url: "/Ch4/api/destroy.php",
        idAttribute: "Code"
    });
    var stuE = new student({
        Code: "10107"
    });
    stuE.destroy({
        success: function (model, response) {
            if (response.code == "0") {
                console.log("Code为 " +
                model.get("Code") + " 的数据已删除");
            }
        },
        error: function (error) {
            onsole.log("删除数据出现异常");
        },
        wait:true
    });
  • 集合相关:自定义集合对象
 var student = Backbone.Model.extend({
        defaults: {
            Code: "",
            Name: "",
            Score: ""
        }
    });
    var stulist = Backbone.Collection.extend({
        model: student
    });
    var stumodels = [{
        Code: "10104",
        Name: "周小敏",
        Score: "500"
    }, {
        Code: "10105",
        Name: "陆明明",
        Score: "300"
    }, {
        Code: "10107",
        Name: "陈天豪",
        Score: 720
    }];
    var stus = new stulist(stumodels);
    for (var i = 0; i < stus.models.length; i++) {
        console.log(stus.models[i].toJSON());
    }
  • 直接实例化集合对象
 var student = Backbone.Model.extend({
        defaults: {
            Code: "",
            Name: "",
            Score: ""
        }
    });
    var stulist = Backbone.Collection.extend({
        model: student
    });
    var stumodels = [{
        Code: "10104",
        Name: "周小敏",
        Score: "500"
    }, {
        Code: "10105",
        Name: "陆明明",
        Score: "300"
    }, {
        Code: "10107",
        Name: "陈天豪",
        Score: 720
    }];
    var stus = new stulist(stumodels);
    for (var i = 0; i < stus.models.length; i++) {
        console.log(stus.models[i].toJSON());
    }
  • 对集合添加一个过滤函数
var student = Backbone.Model.extend({
        defaults: {
            Code: "",
            Name: "",
            Score: 0
        }
    });
    var stulist = Backbone.Collection.extend({
        model: student,
        good: function () {
            return this.filter(function (stu) {
                return stu.get("Score") > 400;
            });
        }
    });
    var stumodels = [{
        Code: "10104",
        Name: "周小敏",
        Score: "500"
    }, {
        Code: "10105",
        Name: "陆明明",
        Score: "300"
    }, {
        Code: "10107",
        Name: "陈天豪",
        Score: 720
    }];
    var stus = new stulist(stumodels);
    var stug = stus.good();
    for (var i = 0; i < stug.length; i++) {
        console.log(stug[i].toJSON());
    }
  • 移除模型对象
    1)remove方法的功能是从指定的集合对象中移除一个或多个模型对象,该方法的调用格式如下。
    obj.remove(models,options)
    其中,obj为实例化后的集合对象,models为一个或多个模型对象,options为配置对象,可以在该对象中设置silent属性等。
    2)pop方法的功能是移除集合对象中最后一个模型对象,该方法的调用格式如下。
    obj.pop(options)
    3)shift方法的功能是移除集合对象中首个模型对象,该方法的调用格式如下。
    obj.shift(options)
    在上述pop和shift方法的调用格式中,各参数与remove的功能一样,不再赘述。接下来通过一个简单的示例来介绍这些方法的使用过程。
var student = Backbone.Model.extend({
        defaults: {
            Code: "",
            Name: "",
            Score: 0
        }
    });
    var stumodels = [{
        Code: "10101",
        Name: "刘真真",
        Score: 530
    }, {
        Code: "10102",
        Name: "张明基",
        Score: 460
    }, {
        Code: "10103",
        Name: "舒虎",
        Score: 660
    }, {
        Code: "10104",
        Name: "周小敏",
        Score: 500
    }, {
        Code: "10106",
        Name: "占小方",
        Score: 380
    }, {
        Code: "10107",
        Name: "陈天豪",
        Score: 720
    }];
    var stus = new Backbone.Collection(stumodels, {
        model: student
    });
    //删除第1条模型对象
    stus.shift();
    //删除第4条模型对象
    stus.remove(stus.models[3]);
    //删除最后一条模型对象
    stus.pop();
    //重新输出全部的模型对象
    for (var i = 0; i < stus.models.length; i++) {
        console.log(stus.models[i].toJSON());
    }
  • 添加集合对象的模型

1)add方法与remove方法对应,功能是向集合对象中指定的位置插入模型对象,如果没有指定位置,默认为集合对象的尾部。该方法的调用格式如下。
obj.add(models,options)
2)push方法与pop方法对应,功能是向集合对象的尾部插入模型对象。它的功能与add方法类似,只是明确了插入的位置,该方法的调用格式如下。
obj.push(models,options)
3)unshift方法与shift方法对应,功能是向集合对象的头部插入模型对象。它的功能与pop方法类似,只是插入的位置不同,该方法的调用格式如下。
obj.unshift(models,options)
上述三种方法使用的参数与add使用的参数说明基本相同,不再赘述。接下来通过一个简单的示例来介绍这些方法的使用过程。


    var student = Backbone.Model.extend({
        defaults: {
            Code: "",
            Name: "",
            Score: 0
        }
    });
    var stumodels = [{
        Code: "10101",
        Name: "刘真真",
        Score: 530
    }, {
        Code: "10102",
        Name: "张明基",
        Score: 460
    }, {
        Code: "10103",
        Name: "舒虎",
        Score: 660
    }, {
        Code: "10104",
        Name: "周小敏",
        Score: 500
    }, {
        Code: "10105",
        Name: "陆明明",
        Score: 300
    }, {
        Code: "10106",
        Name: "占小方",
        Score: 380
    }, {
        Code: "10107",
        Name: "陈天豪",
        Score: 720
    }];
    var newmodels = [{
        Code: "10108",
        Name: "李煜",
        Score: 570
    }, {
        Code: "10109",
        Name: "钟舒畅",
        Score: 460
    }, {
        Code: "10110",
        Name: "佟明月",
        Score: 680
    }];
    var stus = new Backbone.Collection(stumodels, {
        model: student
    });
    //在头部位置插入模型对象
    stus.unshift(newmodels[1]);
    //在索引号为5的位置插入模型对象
    stus.add(newmodels[0], { at: 5 });
    //在尾部位置插入模型对象
    stus.push(newmodels[2]);
    //重新输出全部的模型对象
    for (var i = 0; i < stus.models.length; i++) {
        console.log(stus.models[i].toJSON());
    }
  • 三种办法获取集合中的对象
    1)get方法的功能是通过指定的ID号获取集合中的某一个模型对象,它的调用格式如下。
    obj.get(id)
    其中,obj为实例化后的集合对象,参数ID为模型对象在产生时的唯一标志,也是用于与服务器保持同步的唯一编号,它的正式名称为小写的ID,如果在构建模型对象类中,没有该属性,也可以通过idAttribute属性值指定其他数字类型的属性为id标志,一旦某属性被指定为id标志,它将过滤重复的属性值,不能增加与该属性值相同的模型对象。
    2)at方法的功能是通过指定的索引号获取集合中的某一个模型对象,它的调用格式如下。
    obj.at(index)
    其中,obj为实例化后的集合对象,参数index为集合对象中模型数据的索引号,该索引号以0开始,最大值为obj.models.length-1。
    3)findWhere方法的功能是查找与属性名称和属性值相匹配的第一个模型对象,调用格式如下。
    obj.findWhere(attrs)
    其中,除了obj为实例化后的集合对象外,参数attrs为key/value形式的属性值对象,atts参数只能添加一个组key/value形式的属性值,多组属性值以最后一组为准。
    4)where方法的功能是查找与属性名称和属性值相匹配的第一个模型或多个模型对象。与findWhere方法相比,通过新增加的参数可以决定它查找时返回的对象模型数量,调用格式如下。
    obj.where(attrs, first)
    其中,参数attrs与findWhere方法的使用说明相同。而新增加的first参数是一个布尔类型的值,当该参数为true时,表示返回与属性名称和属性值相匹配的第一个模型对象,这时的功能与findWhere方法相同;而当该参数为false时,表示返回与属性名称和属性值相匹配的全部模型对象是一个数组集合。
    var student = Backbone.Model.extend({
        defaults: {
            Code: "",
            Name: "",
            Score: 0
        },
        idAttribute: "Code"
    });
    var stumodels = [{
        Code: "10101",
        Name: "刘真真",
        Score: 530
    }, {
        Code: "10102",
        Name: "张明基",
        Score: 660
    }, {
        Code: "10103",
        Name: "舒虎",
        Score: 660
    }, {
        Code: "10104",
        Name: "周小敏",
        Score: 500
    }, {
        Code: "10105",
        Name: "陆明明",
        Score: 300
    }, {
        Code: "10106",
        Name: "占小方",
        Score: 380
    }, {
        Code: "10107",
        Name: "陈天豪",
        Score: 720
    }];
    //输出全部的模型对象
    for (var i = 0; i < stus.models.length; i++) {
        console.log(stus.models[i].toJSON());
    }
    console.log("----------------查询结果----------------");
    //查找ID号为10106的对象模型
    var find_id_model = stus.get(10106);
    //查找索引号为6的对象模型
    var find_at_model = stus.at(6);
    //查找与属性名称和值相匹配的对象模型
    var find_0_model = stus.findWhere({
        Score: 660
    });
    var find_1_model = stus.where({
        Score: 660
    },true);
    var find_2_model = stus.where({
        Score: 660
    }, false);
    //以对象的形式输出模型内容
    console.log(find_id_model.toJSON());
    console.log(find_at_model.toJSON());
    console.log(find_0_model.toJSON());
    console.log(find_1_model.toJSON());
    for (var i = 0; i < find_2_model.length; i++) {
        console.log(find_2_model[i].toJSON());
    }
  • 模型对象的排序
    在上一节中介绍了如何查询集合中的模型对象,此外,集合类还提供了对集合中模型对象排序的功能,只需要调用sort方法,其调用格式如下。
    obj.sort(options)
    其中,obj为实例化后的集合对象,options参数为排序过程中的配置对象,在该对象中可以设置silent等属性。在集合对象调用sort方法之前,必须在实例化集合对象时添加一个名为”comparator”的方法。如果不添加该方法,可调用sort,则提示”Cannot sorta setwithout acomparator”异常信息。
    在添加comparator方法时,需要设置两个参数model_1和model_2,分别对应两个相邻的模型对象。通过两个模型对象的排序属性值的比较,设置按该属性名称排序的顺序。如果按升序排列,当前者大于后者时,返回1值;如果按降序排列,当前者大于后者时,返回0值;当调用集合对象执行sort方法功能时,则按该返回值进行排序。
    集合对象的sort方法功能十分强大,全部的排序操作都是自动完成的,且无论是新增或移除集合中的任意模型对象后,该方法又将自动被调用,对集合中的全部模型对象又将按照排序规则进行重新排序,以确定排序的延续性。接下来通过一个简单的示例来介绍该方法的使用过程。
    var student = Backbone.Model.extend({
        defaults: {
            Code: "",
            Name: "",
            Score: 0
        },
        idAttribute: "Code"
    });
    var stumodels = [{
        Code: "10101",
        Name: "刘真真",
        Score: 530
    }, {
        Code: "10102",
        Name: "张明基",
        Score: 660
    }, {
        Code: "10103",
        Name: "舒虎",
        Score: 660
    }, {
        Code: "10104",
        Name: "周小敏",
        Score: 500
    }, {
        Code: "10105",
        Name: "陆明明",
        Score: 300
    }, {
        Code: "10106",
        Name: "占小方",
        Score: 380
    }, {
        Code: "10107",
        Name: "陈天豪",
        Score: 720
    }];
    var stus = new Backbone.Collection(stumodels, {
        model: student,
        comparator: function (model_1, model_2) {
            var intcomp = model_1.get('Score') >
                    model_2.get('Score');
            return intcomp ? 0 : 1;
        }
    });
    stus.sort();
    //增加和删除模型前排序输出全部的模型对象
    for (var i = 0; i < stus.models.length; i++) {
        console.log(stus.models[i].toJSON());
    }
    stus.remove(stus.models[3]);
    stus.add({
        Code: "10108",
        Name: "李煜",
        Score: 570
    });
    console.log("----------------排序结果----------------");
    //增加和删除模型前排序后输出全部的模型对象
    for (var i = 0; i < stus.models.length; i++) {
        console.log(stus.models[i].toJSON());
    }
  • 集合对象与服务器的交互
    与数据模型对象类似,集合对象也可以通过调用本身类中提供的fetch方法与服务器进行交互,获取服务器返回的数据,其调用格式如下所示。
    obj.fetch(options)
    其中,参数obj为集合对象,options为与服务器进行交互过程的配置对象。在该对象中,可以添加success方法,表示当与服务器交互成功后将会调用该方法。此外,当集合对象与服务器的数据交互成功,即调用了自定义的success方法时,还会触发集合对象的reset事件。但该事件不会自动触发,需要在fetch方法的options对象中将reset属性值设置为true,否则不会触发。在该事件中,可以进一步对获取的数据进行下一步的操作,例如显示在页面或进行存储。接下来通过一个简单的示例介绍该方法的使用过程。
    示例5-8 调用fetch方法获取服务器数据
    1.功能描述
    首先,采用extend方法构建一个名为stulist的集合类,并在该类的构造函数initialize中,使用on方法绑定类别对象的reset事件。当触发该事件时,将遍历传回的数据集合,并以JSON格式在浏览器的控制台输出全部模型对象。此外,在集合类中设置url属性,用于设置与服务器请求时的路径。
    然后,实例化一个名为stus的集合对象,并调用fetch方法与服务器进行数据交互,在调用fetch方法过程中,为了能够在成功获取服务器数据时触发reset事件,必须将reset属性值设置为true。此外,添加success方法,当成功获取服务器数据时,将会执行该方法中的代码将获取的数据进行遍历,并以JSON格式的方式输出全部的模型对象。
    2.实现代码
    在页面的<script>元素中,加入如代码清单5-8所示的代码。
   var student = Backbone.Model.extend({
        defaults: {
            Code: "",
            Name: "",
            Score: 0
        }
    });
    var stulist = Backbone.Collection.extend({
        initialize: function () {
            console.log("-----reset事件触发------");
            this.on("reset", function (render) {
                for (var i = 0; i < render.models.length; i++) {
                    console.log(render.models[i].toJSON());
                }
            });
        },
        model: student,
        url: "/Ch5/api/fetch.php"
    });
    var stus = new stulist();
    stus.fetch({
        reset: true,
        success: function (collection, resp, options) {
            console.log("-----请求成功时触发------");
            for (var i = 0; i < collection.models.length; i++) {
                console.log(collection.models[i].toJSON());
            }
        }
    });
    fetch.php文件的功能是定义一个JSON格式的数据,当客户端请求时向客户端返回该数据,fetch.php文件的代码如下。
    <?php
            $stulist = array (
                    array("Code" => "10101", "Name" => "刘真真", "Score" => "530"),
    array("Code" => "10102", "Name" => "张明基", "Score" => "460"),
    array("Code" => "10103", "Name" => "舒虎", "Score" => "660"),
    array("Code" => "10104", "Name" => "周小敏", "Score" => "500"),
    array("Code" => "10105", "Name" => "陆明明", "Score" => "300"),
    );
    echo json_encode($stulist);
    ?>

*调用create方法同步数据
在Backbone中,集合对象的create方法与模型对象的save方法相似,都是向服务器发送模型对象,进行数据同步操作。而集合对象在调用create方法时,先根据对象本身所依附的模型类新建一个模型对象,当与服务器数据同步成功后,再将该新建的模型对象添加至集合对象中。create方法的调用格式如下所示。
obj.create(model, options)
其中,参数obj为集合对象,model参数为发送给服务器的模型对象,参数options则为发送时的方法配置对象。
在集合对象调用create方法过程中,会使用POST和PUT两种Request Method方法向服务器发送数据,前者表示创建模型对象,后者则为修改模型对象。此外,集合对象调用create方法后,如果绑定集合对象的add事件,还会自动触发该事件。
另外,在集合对象调用create方法时,可以通过方法的配置对象设置一些与发送相关的属性,如添加success方法和wait、silent属性,用于控制客户端在与服务器同步过程中的一些操作。此外,当集合对象调用create方法向服务器发送数据时,会通过模型内部的isNew方法检测数据是否是新建还是更新,如果是新建,会使用POST方式,否则使用PUT方式。接下来分别进行说明。
首先定一个名为student的模型类,使用defaults属性设置默认的属性项。然后使用extend方式定义一个名为stulist的集合类,在定义集合类时,使用model属性设置所依附模型类的名称,url属性设置与服务器同步数据的地址。最后实例化一个名为stus的集合对象,调用该对象的create方法向服务器发送模型对象,进行数据同步。

   var student = Backbone.Model.extend({
        defaults: {
            Code: "10001",
            Name: "张三",
            Score: 100
        }
    });
    var stulist = Backbone.Collection.extend({
        model: student,
        url: "/Ch5/api/create.php"
    });
    var stus = new stulist();
    stus.create({
        Code: "10107",
        Name: "陶国荣",
        Score: 750
    });
    服务器的数据接收页create.php是一个PHP文件,功能是声明接收数据的格式,获取发送的数据,向客户端返回成数据保存标志,create.php文件的代码如下。
    <?php
//设置接收数据的格式
            header('Content-Type: application/json; charset=utf-8');
    //获取客户端发送来的数据
    $data = json_decode(file_get_contents("php://input"));
    获取各个属性值,保存至服务器中
            ...
    */
//返回更新成功的标志
    die(json_encode(array('code'=>'206')));
    ?>
  • add事件
    在本示例中,当定义集合类时,在构造函数中绑定名为”add”的添加模型对象事件,当集合对象在添加模型对象时,将会触发该事件。在该事件中,将在浏览器的控制台以JSON格式输出添加的模型对象内容。
var student = Backbone.Model.extend({
defaults: {
Code: "10001",
Name: "张三",
Score: 100
},
idAttribute: "Code"
});
var stulist = Backbone.Collection.extend({
initialize: function () {
//初始化时监听对象添加事件
this.on("add", function (model, response, options) {
console.log(stus.models[0].toJSON());
});
},
model: student,
url: "/Ch5/api/create.php"
});
var stus = new stulist();
stus.create({
Code: "10107",
Name: "陶国荣",
Score: 750
});

源码分析
当集合对象stus调用create方法完成与服务器数据交互之后,由于向集合对象stus自动添加了与服务器同步的模型对象,触发绑定的add集合对象事件根据返回的model参数,获取已发送的模型对象,并以JSON的格式在浏览器的控制台中输出。详细效果见图5-10中第一行的输出内容。
在前面提到过,当一个集合对象在通过调用create方法完成与服务器数据同步之后,默认情况下,会自动将已同步后的模型对象添加到这个集合对象中,但也可以通过设置create方法中配置对象(options)的属性值来改变这个默认流程。
当调用create方法并将配置对象的wait属性值设为true时,表示只有当客户端与服务器数据成功完成数据同步之后,才能将发送的模型对象添加至集合对象中。如果将wait属性值设为false或不添加该属性时,则直接将发送的模型对象添加至集合对象中。
此外,当silent属性值设置为true时,表示不管客户端与服务器是否成功完成同步数据的操作,都会将发送的模型对象添加至集合对象中。如果将silent属性值设为false或不添加该属性时,只有当客户端与服务成功完成数据同步后,才会将发送的模型对象添加至集合对象中。


本示例与示例5-10相比,首先修改集合类中url属性,将该属性值修改为一个不能正常请求的URL地址。其次,在集合对象调用的create方法中,通过第二个参数——配置对象添加wait属性和success方法,并将wait属性值设置为true,在success方法中,将服务器返回的JSON格式值输出至浏览器的控制台中。如果不添加wait属性项或将wait属性值设置为false时,浏览器控制台输出的结果又不相同。

  var student = Backbone.Model.extend({
        defaults: {
            Code: "10001",
            Name: "张三",
            Score: 100
        },
        idAttribute: "Code"
    });
    var stulist = Backbone.Collection.extend({
        initialize: function () {
//初始化时监听对象添加事件
            this.on("add", function (model, response, options) {
                console.log(stus.models[0].toJSON());
            });
        },
        model: student,
        url: "/Ch5/api/create2.php"
    });
    var stus = new stulist();
    stus.create({
        Code: "10107",
        Name: "陶国荣",
        Score: 750
    },{
        wait: true,
        success: function (model, response, options) {
            console.log(response.changed.code);
        }
    });

由于与服务器的数据同步地址异常,无法完成客户端与服务器的数据同步操作,因此浏览器返回404代码。此外,在调用create方法时,通过配置对象添加了wait属性,并将该属性值设置为true,表示只有当客户端与服务器成功完成数据同步之后,才会将同步的模型对象数据添加至集合对象中。因此,同步数据异常时进行数据添加,也不会触绑定的集合对象add事件,效果如图5-11所示。
集合对象在调用create方法时,不添加wait属性或将该属性的值设置为false时,表示不管客户端与服务器的数据同步操作是否成功,都会将同步的模型对象数据添加至集合对象中。因此,将触发绑定的集合对象add事件,在浏览器的控制台中输出同步的模型对象,效果如图5-11所示。
除了在create方法的配置对象中添加wait属性外,还可以添加silent属性,但它们的作用正好相反。如果添加silent属性并将该属性值设置为true,属于静默式同步,不需要客户端与服务器数据同步成功,就可以向集合对象添加模型数据,与不添加wait属性或将该属性的值设置为false时的效果一样。
此外,当集合对象调用create方法并成功与服务器同步数据时,将会执行配置对象中添加的success方法。在该方法中,可以通过返回的changed对象获取服务器传回的code值,完整实现的方法见本示例的代码部分。

  • view部分
 var testview = Backbone.View.extend({
            id: 'show',
            className: 'cls_6',
            render: function (content) {
                this.el.innerHTML = content;
                document.body.appendChild(this.el);
            }
        });
        var test = new testview();
        test.render("backbone是构建前端MVC的利器");

会出现一个id为show,class为class_6的一个元素。

在上述页面文件的JavaScript代码中,为了动态创建一个DOM元素,首先定义id和className属性,分别对应元素的ID和样式属性名称。这些属性还包括tagName和attributes,前者为新元素的名称,如果不设置,则为div元素;后者则是一个对象,它可以该元素的其他属性值,这些新设置的属性都会在元素添加时一起生效,

另外一种方法:设置el属性访问:

<script type="text/javascript">
var testview = Backbone.View.extend({
el: '#show',
render: function (content) {
this.el.innerHTML = content;
}
});
var test = new testview();
test.render("backbone是构建前端MVC的利器");
</script>

通过view访问model中的模型对象

var student = Backbone.Model.extend({
            defaults: {
                Code: "",
                Name: "",
                Score: 0
            }
        });
        var stus = new student({
            Code: "10107",
            Name: "陶国荣",
            Score: 750
        });
        var stusview = Backbone.View.extend({
            el: '#show',
            render: function () {
                this.el.innerHTML = JSON.stringify(this.model);
            }
        });
        var stuv = new stusview({ model: stus });
        stuv.render();
  • 通过view实例化模版
<script type="text/template" id="score-tpl">
    <%= score>600 ? "优秀":"及格"%>
</script>
<script type="text/javascript">
    var stuview = Backbone.View.extend({
        el: $("#score"),
        initialize: function () {
            this.template = _.template($("#score-tpl").html());
        },
        render: function (pscore) {
            this.$el.html(this.template({ score: pscore }));
        }
    });
    //实例化一个view视图
    var stuv = new stuview();
    stuv.render(600)
</script>
  • 通过view实例化多项内容的模版
<script type="text/javascript">
    var student = Backbone.Model.extend({
        defaults: {
            Code: "",
            Name: "",
            Score: 0
        }
    });
    var stus = new student({
        Code: "10107",
        Name: "陶国荣",
        Score: 750
    });

    var stuview = Backbone.View.extend({
        el: $("#ulshowstus"),
        initialize: function () {
            this.template = _.template($("#stus-tpl").html());
        },
        render: function () {
            this.$el.html(this.template(this.model.toJSON()));
        }
    });
    //实例化一个view视图
    var stuv = new stuview({ model: stus });
    stuv.render();
</script>

以下是一个关联事件的应用的代码:

<script type="text/javascript">
var stuview = Backbone.View.extend({
el: $("body"),
initialize: function () {
this.render();
},
render: function () {
this.$el.append('<div id="backbone">
backbone是构建前端MVC的利器</div>');
},
events: {
'click div#backbone': 'togcls'
},
togcls: function () {
$("#backbone").toggleClass("changed");
}
});
//实例化一个view视图
var stuv = new stuview();
</script>
  • 动态绑定和取消绑定
    delegateEvents方法的功能是重新绑定events属性值中已声明的全部元素事件,其调用格式如下代码所示。
delegateEvents([events])

undelegateEvents方法的功能是取消所有已绑定元素的事件,其调用格式如下所示。

undelegateEvents()

一个例子

<script type="text/template" id="main-tpl">
<input id="btn_a" type="button" value="切换样式" />
<input id="btn_b" type="button" value="取消绑定" />
<input id="btn_c" type="button" value="重新绑定"
       onclick="stuv.rebind()" />
</script>
</body>
<script type="text/javascript">
var stuv = null;
var stuview = Backbone.View.extend({
    el: $("#main"),
    initialize: function () {
        this.template = _.template($("#main-tpl").html());
        this.render();
    },
    render: function () {
        this.$el.html(this.template());
    },
    rebind: function () {
        this.delegateEvents(this.events);
    },
    events: {
        'click input#btn_a': 'btnclick_a',
        'click input#btn_b': 'btnclick_b'
    },
    btnclick_a: function () {
        $("#backbone").toggleClass("changed");
    },
    btnclick_b: function () {
        this.undelegateEvents();
    }
});
//实例化一个view视图
stuv = new stuview();
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值