因为要遵循KISS(Keep It Simple Stupid)原则,尽可能使事情简单
把应用拆分成多个文件,每个包含下面一种类型:(1)视图(2)模板(3)路由器(4)集合(5)模型
此文是对《BackBone.js的第一个应用,相当于Hello World!》《BackBone.js集合》《BackBone.js的事件绑定例子》《Backbone.js中Underscore.js的视图和子视图》中代码的重构整理。
此代码来自于《JavaScript快速全栈开发》中,经过网络其他的学习掺杂整理出来的代码。提醒:要用谷歌浏览器和火狐浏览器哦~
(1)在html中写入script标签引入拆分的文件:
<script src="fruit_item_view.js"></script>
<script src="fruit_fruitView_view.js"></script>
<script src="fruit_view.js"></script>
<script src="fruit.js"></script>
<script src="fruit_app.js"></script>
(2)将相应的代码复制到相应的js文件里面即可
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<title>Backbone.js小例子的代码重构</title>
<script src="jquery.js"></script>
<script src="underscore.js"></script>
<script src="backbone.js"></script>
<script src="fruit_item_view.js"></script>
<script src="fruit_fruitView_view.js"></script>
<script src="fruit_view.js"></script>
<script src="fruit.js"></script>
<script src="fruit_app.js"></script>
</head>
<body>
</body>
</html>
fruit_item_view.js
//Fruit的视图只包含两个属性template和render
var collectionView = Backbone.View.extend({
initialize:function(){
this.model = new (Backbone.Model.extend({}));
this.model.on('change',this.render,this);
this.on('spinner',this.showSpinner,this);
},
//为了让Underscore.js模板引擎可以更好的处理这个任务,需要给figure、img、figcaption标签展示特定的值
//为了保证阅读性,使用反斜杠作为结束符,或+来连接字符串
template:_.template('<figure>\<img src="<%=attributes.url%>"/>\<figcaption><%=attributes.name%></figcaption>\<figure>'),
templateSpinner:'<img src="img/spinner.gif" width="500">',
loadCollection:function(collectionName){
this.trigger('spinner');
var view = this;//需要在闭包里访问view
setTimeout(function(){
//模拟从远程服务器获取数据消耗的时间
view.model.set(view.collection.where({
name:collectionName
})[0].attributes);
},1000);
},
render:function(collectionName){
//用where方法和[]选择第一个元素作为模型
var fruitHtml = this.template(this.model);
$('body').html(fruitHtml);
},
showSpinner:function(){
$('body').html(this.templateSpinner);
}
});
fruit_fruitView_view.js
//让fruitView可以使用整个数据库。
//用jQuery选择器字符串作为值的属性给fruitView
var fruitView = Backbone.View.extend({
el:'body',
listEl:'.colletionType-list',
cartEl:'.cart-box',
template:_.template('Fruit Data:\<ul class="colletionType-list"></ul>\<div class="cart-box"></div>'),
initialize: function() {
this.$el.html(this.template);
this.collection.on('addToCart', this.showCart, this);
},
showCart: function(fruitModel) {
$(this.cartEl).append(fruitModel.attributes.name+'<br/>');
},
render:function(){
view = this;
//需要在闭包里访问view
this.collection.each(function(fruit){
//使用水果模型创建子视图
var fruitSubView = new fruitItemView({model:fruit});
//使用单个水果视图数据渲染模板
fruitSubView.render();
//把渲染好的子视图里的jQuery对象添加到水果列表DOM元素里面
$(view.listEl).append(fruitSubView.$el);
});
}
});
fruit_view.js
//Fruit的视图只包含两个属性template和render
var collectionView = Backbone.View.extend({
initialize:function(){
this.model = new (Backbone.Model.extend({}));
this.model.on('change',this.render,this);
this.on('spinner',this.showSpinner,this);
},
//为了让Underscore.js模板引擎可以更好的处理这个任务,需要给figure、img、figcaption标签展示特定的值
//为了保证阅读性,使用反斜杠作为结束符,或+来连接字符串
template:_.template('<figure>\<img src="<%=attributes.url%>"/>\<figcaption><%=attributes.name%></figcaption>\<figure>'),
templateSpinner:'<img src="img/spinner.gif" width="500">',
loadCollection:function(collectionName){
this.trigger('spinner');
var view = this;//需要在闭包里访问view
setTimeout(function(){
//模拟从远程服务器获取数据消耗的时间
view.model.set(view.collection.where({
name:collectionName
})[0].attributes);
},1000);
},
render:function(collectionName){
//用where方法和[]选择第一个元素作为模型
var fruitHtml = this.template(this.model);
$('body').html(fruitHtml);
},
showSpinner:function(){
$('body').html(this.templateSpinner);
}
});
fruit.js
//CollectionType的Backbone Collection非常干净
var CollectionType = Backbone.Collection.extend({});
fruit_app.js
//准备一些数据,会提供名称和图像的URL
var fruitData = [{name:"watermelon",url:"img/watermelon.jpg"},{name:"orange",url:"img/orange.jpg"}];
var app;
var router = Backbone.Router.extend({
routes:{
"":'fruit',
//用户浏览index.html#collectionType/名称时即可看到存储的某一个信息。
//这个信息由Backbone Router里定义的loadCollection函数获取和渲染
'collectionType/:collectionName':'loadCollection'
},
//创建Bacckbone Colelction使它和fruitData变量绑定,把集合传递给fruitView及collectionView
initialize:function(){
var collectionType = new CollectionType();
collectionType.reset(fruitData);
this.fruitView = new fruitView({collection:collectionType});
this.collectionView = new collectionView({collection:collectionType});
},
fruit:function(){
this.fruitView.render();
},
loadCollection:function(collectionName){
this.collectionView.loadCollection(collectionName);
}
});
//为单个水果创建一个子视图
var fruitItemView = Backbone.View.extend({
tagName:'li',
//模板是一个使用Underscore.js函数构建的字符串
template: _.template('\
<a href="#collectionType/<%=name%>" target="_blank">\
<%=name%>\
</a> <a class="add-to-cart" href="#">buy</a>\
'),
//格式:事件+jQuery选择器:函数名
//如:'click . add-to-cart' : 'addToCart'
// 'click #load-more' : 'loadMoreData'
events:{'click .add-to-cart':'addToCart'},
render:function(){
//使用this.$el上的jQuery方法html()来展示列表里每一项,根据tagName指定的<li>元素
this.$el.html(this.template(this.model.attributes));
},
addToCart:function(){
this.model.collection.trigger('addToCart',this.model);
}
});
$(document).ready(function(){
app = new router;
Backbone.history.start();
})
(3)已经完善,即可查看效果。
源代码免费提供给大家,希望大家一起交流学习。感谢。http://download.csdn.net/detail/miss_ll/9699070