在backbone.js中使用下划线模板渲染

Rendering in backbone.js with underscore templates

本文关键字:下划线 backbone js      更新时间:2023-09-26

我尝试使用下划线的模板呈现项目列表。但它什么也没显示。

我尝试创建2个视图,一个是任务,一个是任务列表,但我被困在使用模板。

  • .render()做什么?
  • 如果我使用模板,我还需要渲染吗?

我认为数据将映射模板变量当你做this.$el.html(template_var) ?

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>
        <script type="text/template" id="task_list">
            <li><%=title%></li>
            <li><%=priority%></li>
        </script>
        </script>
<script type="text/javascript">
        (function(){
        window.App = {
            Models:{},
            Collections:{},
            Views:{}
        };
        window.template = function(id){
            return _.template( $('#' + id).html() );
        }
        
        App.Models.Task = Backbone.Model.extend({
                title: 'default',
                priority: 1
        });
        App.Collections.Task = Backbone.Collection.extend({
            model: App.Models.Task
        });
        App.Views.Task = Backbone.View.extend({
            template: template('task_list'),
            render(){
                var template = this.template( this.model.toJSON() );
                console.log(template)
                this.$el.html(template);
                return this;
            }
        })
        App.Views.Tasks = Backbone.View.extend({
            tagName: 'ul',
            render: function(){
                this.collection.each( this.addOne, this);
                return this;
            },
            addOne: function(task){
                var taskView = new App.Views.Task({ model: task})
                taskView.render();
                this.$el.append(taskView.render().el);
            }
        })
        var tasks = new App.Collections.Task([
            {
                    title: 'Go to store',
                    priority: 4
                },
                {
                    title: 'Eat',
                    priority: 3
                },
                {
                    title: 'Sleep',
                    priority: 4
                }
        ])
        var tasksView = new App.Views.Tasks({collection: tasks})
        $('body').html(tasksView.el)
        })()
</script>
</body>
</html>

你真的很接近了,但是还是有一些小问题。

Backbone做了很多事情,但有一件事它没有为你做,那就是渲染逻辑,这完全取决于开发人员。所以,你需要:

  • 一个模板,用来将HTML从JS逻辑中分离出来。
  • 一个render函数,使用你最喜欢的技术进行渲染,在我们的例子中是jQuery。

主干视图总是有一个根DOM元素(el),即使它还没有呈现,这是一个div默认如果没有指定tagName

你的任务视图是这样呈现的:

<div>
    <li>Go to store</li>
    <li>4</li>
</div>

我稍微改变了一下模板。


我将CSS移回HEAD部分。这是一个标准,但并不是真正的问题之一。


模型中的默认属性应该在defaults属性中指定。


使用以下简写语法定义函数仅在ES6 (ECMAScript 2015)中可用。

render(){

从ECMAScript 2015 (ES6)开始,引入了对象初始化器上的方法定义的更短语法。它是赋值给方法名的函数的简写。

为了使它与大多数浏览器兼容,你应该使用:

render: function() {

你还忘了在列表视图上调用render。

$('body').html(tasksView.el)
应:

$('body').html(tasksView.render().el);

因为你的代码在IIFE中,你不需要用window使你的应用程序和函数全局化,一个本地的var就足够了,是一个更好的编码实践。


<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- CSS should be in the head -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
    <script src="http://underscorejs.org/underscore.js"></script>
    <script src="http://backbonejs.org/backbone.js"></script>
    <script type="text/template" id="task_list">
        <%=title%> (<%=priority%>)
    </script>
    <script type="text/javascript">
        (function() {
            var App = {
                Models: {},
                Collections: {},
                Views: {}
            };
            function template(id) {
                return _.template($('#' + id).html());
            }
            App.Models.Task = Backbone.Model.extend({
                defaults: {
                    title: 'default',
                    priority: 1
                }
            });
            App.Collections.Task = Backbone.Collection.extend({
                model: App.Models.Task
            });
            App.Views.Task = Backbone.View.extend({
                template: template('task_list'),
                tagName: 'li',
                render: function() {
                    var template = this.template(this.model.toJSON());
                    console.log(template)
                    this.$el.html(template);
                    return this;
                }
            });
            App.Views.Tasks = Backbone.View.extend({
                tagName: 'ul',
                render: function() {
                    this.collection.each(this.addOne, this);
                    return this;
                },
                addOne: function(task) {
                    var taskView = new App.Views.Task({
                        model: task
                    })
                    this.$el.append(taskView.render().el);
                }
            });
            var tasks = new App.Collections.Task([{
                title: 'Go to store',
                priority: 4
            }, {
                title: 'Eat',
                priority: 3
            }, {
                title: 'Sleep',
                priority: 4
            }]);
            var tasksView = new App.Views.Tasks({
                collection: tasks
            });
            $('body').html(tasksView.render().el);
        })()
    </script>
</body>
</html>