事件绑定
在我们浏览网页的时候,获取数据并不是一下只就全部获取到的,为了创建一个更好的用户体验,就来模拟一个加载(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文件
:下一篇 »