1

模拟数据

需要添加一些模拟用的数据,并且把它们和视图结合起来。

// 图书数据库
    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变量绑定,把集合传递给homeViewbookView。简单来说,在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字符串的形式展示在浏览器里。这并不是一种用户友好的体验。

BookCollection非常干净和简单:

var Books = Backbone.Collection.extend({});

Backbone在集合中使用fetch()或者reset()方法会自动创建一个模型。

Book视图

Book的视图也不复杂,它只包含两个属性templaterender

var bookView = Backbone.View.extend({
        template: _.template(
            '<h2><%= attributes.name %></h2><img src="<%= attributes.url %>">'
        ),
        // 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方法已经可以加载数据和渲染它了。

完整代码

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>backbone日常练习</title>
</head>

<body>

<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();
        },
        // 渲染apples页面
        loadBook: function (bookName){
            this.bookView.render(bookName);
        }
    });

    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 子视图
    });

    var Books = Backbone.Collection.extend({});

    // apples 视图
    var bookView = Backbone.View.extend({
        template: _.template(
            '<h2><%= attributes.name %></h2><img src="<%= attributes.url %>">'
        ),
        // TODO 用加载苹果过程和事件绑定来重写
        render: function (bookName){
            var bookModel = this.collection.where({name: bookName})[0];
            var bookHtml = this.template(bookModel);
            $('body').html(bookHtml);
        }
    });

    $(function (){
        app = new router;
        Backbone.history.start();
    });

</script>
</body>
</html>

然后在浏览器里面打开index.html,看到从“图书数据库”里面加载到的数据:

clipboard.png

在浏览器里面打开index.html#books/book1,看到书名和书的图片就大功告成了!

clipboard.png


_我已经从中二毕业了
7.9k 声望235 粉丝

不搞前端会死星人。


引用和评论

0 条评论