事件绑定
在我们浏览网页的时候,获取数据并不是一下只就全部获取到的,为了创建一个更好的用户体验,就来模拟一个加载(Spinner)的图片来告诉用户正在获取数据中!
当用户在浏览详细视图(books/:BookName),只需要调用加载数据的方法。然后,因为设置了正确的监听器,当接受到新的数据的时候,视图就会自动更新。数据更新的时候,Backbone支持多事件和自定义事件。
改变路由程序里面的代码:
// 渲染Books页面loadBook: function (bookName){ this.bookView.loadBook(bookName);
}除了bookView类,其他都不会改变。添加构造函数或者initialize方法,initialize方法是Backbone里面的一个特殊的字符属性。每个实例初始化的时候都会调用这个属性对应的方法。
然后使用两个事件——change和spinner的自定义事件。我们将使用on()(别名bind)函数。
initialize: function (){ this.model = new (Backbone.Model.extend({})); this.model.bind('change', this.render, this); this.bind('spinner', this.showSpinner, this);
}上面的代码做了两件简单的事情:
当模型改变时候调用
render()函数当事件
spinner触发时调用showSpinner()函数
然后spinner怎么办呢?,那就用一个简单的gif图片把!在bookView里创建一个新的属性:
templateSpinner: '<img src="img/loding.gif">'
spinner图片(上网找一大堆):
接着回到一开始那个loadBook函数里面,继续写代码:
loadBook: function (bookName){ this.trigger('spinner'); // 出现加载图片
var me = this; // 需要在闭包访问this
setTimeout(function (){ // 模拟从服务器获取数据要的时间
me.model.set(me.collection.where({
name: bookName
})[0].attributes);
}, 1000);
}里面触发了spinner事件,还有为了解决作用域的问题,需要在闭包里面访问this。
setTimerout是为了模拟从服务器获取响应的时间。在它内部里面,使用model.set()和model.attributes(返回模型属性)把选中的模型赋值给当前视图的模型。
最后把render函数里面多余的代码去掉,实现showSpinner函数:
render: function (bookName){ var bookHtml = this.template(this.model);
$('body').html(bookHtml);
},
showSpinner: function (){
$('body').html(this.templateSpinner);
}让后打开浏览器访问index.html#books/book1,如果可以看到加载的图片的话,就证明成功啦!
最后附上完整的代码
<!doctype html><html><head><meta charset="utf-8"><title>backbone日常练习</title></head><body><p><a href="#books/book1">bg</a></p><script src="js/jquery.min.js"></script><script src="js/Underscore.min.js"></script><script src="js/backbone-min.js"></script><script>
var app; // 图书数据库
var booksData = [
{
name: 'book1',
url: 'img/1.jpg'
},
{
name: 'book2',
url: 'img/2.jpg'
}
]; var router = Backbone.Router.extend({
routes: { '': 'home', 'books/:bookName': 'loadBook'
},
initialize: function (){ // 一些在对象初始化的时候执行的代码
var books = new Books();
books.reset(booksData); this.homeView = new homeView({collection: books}); this.bookView = new bookView({collection: books});
},
home: function (){ this.homeView.render();
}, // 渲染Books页面
loadBook: function (bookName){ this.bookView.loadBook(bookName);
}
}); var homeView = Backbone.View.extend({
el: 'body',
template: _.template('books data: <%= data %>'),
render: function (){ this.$el.append(this.template({
data: JSON.stringify(this.collection.models)
}));
} // TODO 子视图
}); var Books = Backbone.Collection.extend({}); // books 视图
var bookView = Backbone.View.extend({
initialize: function (){ this.model = new (Backbone.Model.extend({})); this.model.bind('change', this.render, this); this.bind('spinner', this.showSpinner, this);
},
template: _.template( '<h2><%= attributes.name %></h2><img src="<%= attributes.url %>">'
),
templateSpinner: '<img src="img/loding.gif">',
loadBook: function (bookName){ this.trigger('spinner'); // 出现加载图片
var me = this; // 需要在闭包访问this
setTimeout(function (){ // 模拟从服务器获取数据要的时间
me.model.set(me.collection.where({
name: bookName
})[0].attributes);
}, 1000);
}, // TODO 用加载图书过程和事件绑定来重写
render: function (bookName){ var bookHtml = this.template(this.model);
$('body').html(bookHtml);
},
showSpinner: function (){
$('body').html(this.templateSpinner);
}
});
$(function (){
app = new router;
Backbone.history.start();
});</script></body></html>转自 ( http://segmentfault.com/a/1190000002550271 )
-
« 上一篇:
Backbone.js学习笔记:图书案例-使用集合
-
Linux运行.sh文件
:下一篇 »