在 backbone.js 中查看错误

View error in backbone.js

我正在使用 python 创建一个虚拟服务器来存储 JSON 数据。我正在尝试获取数据以将其显示在仪表板中。我不断收到

cannot read property html of undefined

cannot read property render of undefined

我错过了什么?

我的 backbone 脚本:

// Create a Model
var Dashboard = Backbone.Model.extend({});

// Create a collection
var DashboardCollection = Backbone.Collection.extend({
  model: Dashboard,
  url: 'http://localhost:8889/api/test'
});

// create an instance of the collection object
var jobList = new DashboardCollection();
    jobList.fetch({success:function(){
            test.render();
        }});
        // Create a jobList view
var jobListView= Backbone.View.extend({
    el: $('.jobsList'),
    template: _.template($('#test-template').html()),

    initialize: function(){
        this.render();
        //this.listenTo(this.model, 'change', this.render);
        //this.listenTo(this.model, 'destroy', this.remove);
    },
    render : function(){

        this.$el.html(this.template({'last_name':'test'}));
        return this;
    }
 });

var test = new jobListView;

还有我的HTML:

    <main>
       <div class="row">
            <div class="left glass">
                <!--[if lt IE 9]>
                <div class="legacy-ie-fix"></div>
                <![endif]-->
                <h1>Job List</h1>
                <div class ="jobsList">

                </div>
            </div>
            <div class="right glass">
                <!--[if lt IE 9]>
                    <div class="legacy-ie-fix"></div>
                <![endif]-->
                <h1>Metrics</h1>
                <div id="metrics">
                    <div class="row">
                    </div>
                </div>
            </div>
        </div>
    </main>
</body>
<script type="text/template" id="test-template">
    <table class="table striped">
        <thead>
            <tr>
                <th>Data</th>

            </tr>
        </thead>
        <tbody>
            <tr>
                <td><%= last_name %></td>
            </tr>
        </tbody>
    </table>
</script>

好像是顺序问题

确保文档准备就绪

如果您在脚本中使用 jQuery 从文档中获取元素(如 el: $('.jobsList')),您必须确保 HTML 已准备就绪。您可以将代码包装在 jQuery 样式文档就绪函数中:

$(function() {
    var JobListView = Backbone.View.extend({
        el: $('.jobsList'),
        template: _.template($('#test-template').html()),

        render: function() {

            this.$el.html(this.template({ 'last_name': 'test' }));
            return this;
        }
    });

});

或者只加载 <body> 底部但在其中的脚本。

    <script type="text/template" id="test-template">
       Put the template above the scripts loading and inside the body.
    </script>
    <script src="jquery.js">
    <script src="underscore.js">
    <script src="backbone.js">
    <script src="script/my-app.js">
</body>

页面上 <script> 标签的顺序很重要。 Backbone 需要先加载 jQuery 和 Underscore.js,而您自己的代码需要 Backbone(和 jQuery,但这已经在依赖链中得到处理) .

在使用前先声明并赋值变量

您在集合上调用 fetch,它在分配之前使用视图。虽然它可以工作(参见 var hoisting),但最好在可能的情况下在使用变量之前声明和分配它们。

// Create a list view class
var JobListView = Backbone.View.extend({
    el: '.jobsList', // no need to use jQuery here.
    template: _.template($('#test-template').html()),

    render: function() {

        this.$el.html(this.template({ 'last_name': 'test' }));
        return this;
    }
});

// instantiate the view first.
var test = new JobListView();

// then create an instance of the collection object
var jobList = new DashboardCollection();

// and fetch it when everything is ready.
jobList.fetch({
    success: function() {
        test.render();
    }
});

请注意,JS 自定义类型 (类) 应该在 PascalCase 中,而不是在 snakeCase 中作为普遍认可的标准,但这不会使代码失败。

将元素传递给视图

为了能够在不同的视图和模板中轻松重用您的视图,您应该避免 hard-coding el 属性.

相反,将元素传递给视图:

var JobListView = Backbone.View.extend({
    // ... 
});

// ...somewhere else

var view = new JobListView({ el: '.jobsList' });

或者使用由 Backbone 视图创建的元素。

var JobListView = Backbone.View.extend({
    className: 'jobList',
});

// ...inside a parent view's render
var ParentView = Backbone.View.extend({
    template: '<div class="job-list-1"></div><div class="job-list-2"></div>',
    render: function() {
        this.$el.html(this.template);
        this.$('.job-list-1').html(new JobListView().render().el);
        this.$('.job-list-2').html(new JobListView().render().el);
        // ...
        return this;
    }
});

这将导致:

<div class="job-list-1">
    <div class="jobList"></div>
</div>
<div class="job-list-2">
    <div class="jobList"></div>
</div>