此文是对上一篇文章《Backbone.js的事件绑定例子》的完善。
子视图也是Backbone视图,是在另一个Backbone视图里创建和使用的。
子视图对于分离UI事件(如点击)是很实用的一种方式。
此源码来自《JavaScript快速全栈开发》中,经过网络其他的学习掺杂整理记录下来的。
提醒:推荐使用谷歌浏览器、火狐浏览器查看,360浏览器无效,IE会被拦截。
(1)先引入三个库文件(JQuery.js、Underscore.js、Backbone.js),第一篇Backbone.js的文章中有下载地址和版本号
(2)准备一个img文件夹存放两张图片,分别叫(watermelon.jpg、orange.jpg、spinner.gif)
(3)再写一段js,具体介绍在代码上
<script>
//准备一些数据,会提供名称和图像的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);
}
});
//让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);
});
}
});
//CollectionType的Backbone Collection非常干净
var CollectionType = Backbone.Collection.extend({});
//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);
}
});
$(document).ready(function(){
app = new router;
Backbone.history.start();
})
</script>
(4)具体效果:每个列表项包含水果名字和带有onClick事件“Buy”链接,点击可跳转到对应图片并且点击buy就会出现对应的水果名称。当然输入#collectionType/watermelon的方式也同样有效。
源代码免费提供给大家,希望大家一起交流学习。感谢。http://download.csdn.net/detail/miss_ll/9698974