模拟数据
需要添加一些模拟用的数据,并且把它们和视图结合起来。
// 图书数据库
var booksData = [
{
name: 'book1',
url: 'img/1.jpg'
},
{
name: 'book2',
url: 'img/2.jpg'
}
];
这就是我们的图书数据库。更准确的来说,这是我们的
REST API
的替代品,它会提供给我们图书的名字和图像
添加路由
routes: {
'': 'home',
'books/:bookname': 'loadBook'
}
这样之后我们回去浏览 index.html#books/SOMENAME
的时候可以看到某一些图书的信息。这个信息有Backbone.Router
里定义的loadBook函数获取渲染
loadBook: function (bookName){
this.bookView.render(bookName);
}
注意到
bookName
变量没有?它和我们在routes
里定义的一模一样。这就是在Backbone
里使用查询字符串里面的参数(比如:?param=value&q=search
)的方式。
重构部分代码
现在重构一些代码,包含创建Backbone Collection
,是它和booksData
变量绑定,把集合传递给homeView
及bookView
。简单来说,在Router
的构造函数initialize
里搞定这一些:
initialize: function (){
// 一些在对象初始化的时候执行的代码
var books = new Books();
books.reset(bookData);
this.homeView = new homeView({collection: books});
this.bookView = new bookView({collection: books});
}
好啦,差不多完善了Router
类了,代码:
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.render(bookName);
}
});
还有我们homeView
的代码:
var homeView = Backbone.View.extend({
el: 'body',
template: _.template('books data: <%= data %>'),
render: function (){
this.$el.html(this.template({
data: JSON.stringify(this.collection.models)
}));
}
// TODO 子视图
});
现在只是把JSON字符串的形式展示在浏览器里。这并不是一种用户友好的体验。
Book
的Collection
非常干净和简单:
var Books = Backbone.Collection.extend({});
Backbone在集合中使用
fetch()
或者reset()
方法会自动创建一个模型。
Book视图
Book的视图也不复杂,它只包含两个属性template
和render
。
var bookView = Backbone.View.extend({
template: _.template(
'<%= attributes.name %>
'
),
// TODO 用加载图书过程和事件绑定来重写
render: function (bookName){
var bookModel = this.collection.where({name: bookName})[0];
var bookHtml = this.template(bookModel);
$('body').html(bookHtml);
}
});
<%=
和%>
符号,它告诉Underscore.js
需要展示attributes
对象的url、name
属性。
最后,给bookView
添加render
函数:
render: function (bookName){
var bookModel = this.collection.where({name: bookName})[0];
var bookHtml = this.template(bookModel);
$('body').html(bookHtml);
}
在集合里面使用了
where()
方法和[]选择第一个元素作为模型。现在render
方法已经可以加载数据和渲染它了。
完整代码
backbone日常练习
然后在浏览器里面打开index.html,看到从“图书数据库”里面加载到的数据:
在浏览器里面打开index.html#books/book1,看到书名和书的图片就大功告成了!