视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
使用Backbone.js创建一个增删改查表的实例代码
2020-11-27 20:22:59 责编:小采
文档


Backbone.js是一套重量级的web开发框架,它是基于jquery和underscore的一个js框架,主要由三个部分组成:Model,Collection,View。
1.Model:创建模型来表示数据对象,可以进行数据验证,将对象销毁或者保存到服务器上。
2.Collection:是Model的集合,可以增加或删除元素,以及一些方便的操作。
3.View:可以绑定html模板和事件,可以将模型或者集合渲染到页面上,可以通过监听模型改变或销毁等事件重新渲染页面。
Backbone的优势在于将数据和界面很好的分离开来,将事件的绑定很好的剥离出来,便于管理和迭代,使得Javascript的模块化更加清晰。Backbone比较适合页面上有大量数据的情况,是页面内复杂的信息沟通更清晰。

下面我用Backbone写了一个增删改查的表格,参照了Backbone官网Todos的例子。Backbone.js本身依赖于jquery和underscore,数据存储我用到了backbone-localstorage.js,将数据存储在本地数据库中,我把主要的js代码贴出来。其中用到了很多jquery,underscore和backbone的方法和事件,请参考相关文档。

$(function(){

	//Model:表示一个学生
	var Student=Backbone.Model.extend({
	//默认值
	defaults:function(){
	return{
	name:"XXX",
	age:"0",
	selected:false,
	id:Students.nextId(),
	};
	},
	
	//初始化的时候判断,如果设置的属性值非法就设为默认值
	initialize:function(){
	if(!this.get("name")){
	this.set({"name":this.defaults().name});
	}
	if(!this.get("age")||!(/(^[1-9]\d*$)/.test(this.get("age")))){
	this.set({"age":this.defaults().age});
	}
	},

	//标记该学生是否被选中
	toggle:function(){
	this.save({selected:!this.get("selected")});
	}
	});

	//Collection:Model的集合,即所有学生的集合
	var Students=Backbone.Collection.extend({
	
	model:Student,
	
	//本地数据库,用到backbone-localstorage.js
	localStorage:new Backbone.LocalStorage("Students-Table"),

	//返回被选中的学生的集合
	selected:function(){
	return this.filter(function(student){return student.get('selected');});
	},

	//给每个学生一个编号
	nextId:function(){
	if(!this.length)
	return 1;
	return this.last().get('id')+1;
	}
	});

	//定义一个学生集合对象
	var Students=new Students;


	//View:这个视图表示table中的一列,即一个学生,对应一个Model
	var StudentView=Backbone.View.extend({
	//表示<tr></tr>元素
	tagName:"tr",
	
	//将相应模板写入template属性中,_.template()为underscore.js中的方法
	template:_.template($('#item-template').html()),

	//绑定该tr下的事件
	events:{
	"click .toggle":"toggleSelect",
	"dblclick td":"edit",
	"click a.destroy":"clear",
	"blur .edit":"close"
	},

	//初始化该View,listenTo监听model的事件
	initialize:function(){
	//model发生变化就重新渲染视图
	this.listenTo(this.model,'change',this.render);
	//销毁model
	this.listenTo(this.model,'destroy',this.remove);
	},

	//this.$el为该tr节点元素,将template渲染进该节点,并把model的值写入
	render:function(){
	this.$el.html(this.template(this.model.toJSON()));
	//如果该行被选中,则切换样式
	this.$el.toggleClass('selected',this.model.get('selected'));
	return this;
	},

	//判断该行是否被选中,对应model中的selected属性
	toggleSelect:function(){
	this.model.toggle();
	},

	//双击td将样式变为可编辑
	edit:function(e){
	$(e.currentTarget).addClass("editing").find("input,select").focus();
	},

	//编辑状态下失去焦点,则修改完成
	close:function(e){
	var input=$(e.currentTarget);

	if(input.attr('name')=="name"){
	if(!input.val()){
	input.val(this.model.defaults().name);
	}
	this.model.save({"name":input.val()});
	}else if(input.attr('name')=="gender"){
	this.model.save({"gender":input.val()});
	}else{
	if(!input.val()||!(/(^[1-9]\d*$)/.test(input.val()))){
	input.val(this.model.defaults().age);
	}
	this.model.save({"age":input.val()});
	}
	input.parent().removeClass("editing");
	},

	//删除该行的时候删除相应model
	clear:function(){
	this.model.destroy();
	}
	});


	//View:这个视图表示$("#content"),用来表现整个学生表格
	var AppView=Backbone.View.extend({
	el:$("#content"),

	//右下角删除学生数目的模板
	statsTemplate:_.template($('#stats-template').html()),

	events:{
	"click #add-student":"addNewStudent",
	"click #clear-selected":"clearSelected",
	"click #select-all":"selectAll"
	},

	initialize:function(){
	this.allCheckbox=$("#select-all");
	this.main=$("#main");
	this.footer=$('footer');
	this.name=$("#new-name");
	this.age=$("#new-age");
	this.gender=$("#new-gender");

	//Collection中增加一个Model就触发add事件
	this.listenTo(Students,'add',this.addOne);
	//一旦调用fetch方法就触法reset事件
	this.listenTo(Students,'reset',this.addAll);
	//all事件表示该View下的所有事件,即触法任意事件就触法all事件
	this.listenTo(Students,'all',this.render);

	//从本地数据库中获取所有学生
	Students.fetch();
	},

	//渲染视图
	render:function(){
	var selected=Students.selected().length;
	
	if(Students.length){
	this.main.show();
	this.footer.show();
	this.footer.html(this.statsTemplate({selected:selected}));
	}else{
	this.main.hide();
	this.footer.hide();
	}
	//判断所有学生是否被选中
	this.allCheckbox.attr("checked",selected==Students.length?true:false);
	},

	//增加一个学生,同时将model传入StudentView中
	addOne:function(student){
	var view=new StudentView({model:student});
	//将渲染后的每一列添加到表格中
	this.$("#student-list").append(view.render().el);
	},

	//增加所有学生,通过Collection.each依次调用addOne方法
	addAll:function(){
	Students.each(this.addOne,this);
	},

	//增加一个新学生
	addNewStudent:function(){
	Students.create({name:this.name.val(),gender:this.gender.val(),age:this.age.val()});
	this.name.val('');
	this.age.val('');
	this.gender.val(1);
	},

	//删除选中列,_.invoke(集合,方法)
	clearSelected:function(){
	_.invoke(Students.selected(),'destroy');
	},

	//选中所有
	selectAll:function(){
	var selected=this.allCheckbox.attr('checked')=="checked";
	Students.each(function(student){
	student.save({'selected':selected});
	});
	}
	});

	//创建View
	var App=new AppView;
});

下载本文
显示全文
专题