Backbone JS - View not rendering

2019-09-05 15:33发布

I am trying to get a simple html page to display the retrieved collection data on the html page. There are no errors being thrown so I cannot tell what I'm doing wrong.

The model, collection, and view are being created properly as I can see them in the console with the data that's being retrieved from the API, however the page is not displaying anything on the page. Any help would be greatly appreciated.

Model

Department = Backbone.Model.extend({
  idAttribute: "dept_id",
  urlRoot: appRouteUrl + '/api/v1/departments',
  defaults: {
    dept_code: '',
    dept_desc: ''
  }
});

Collection

DepartmentCollection = Backbone.Collection.extend({
  url: appRouteUrl + '/api/v1/departments',
  model: Department
});

View

var DepartmentListView = Backbone.View.extend({
  template: "#department-list-template",
  tagName: "ul",
  render: function() {
    var results = [];
    var compiledTemplate = _.template(this.template);
    this.collection.each(function(department) {
      console.log(department);
      var html = compiledTemplate(department.toJSON());
      results.push(html);
    });
    this.$el.html(results);
    return this;
  }
});

Index

<!DOCTYPE html>
<html>

<head>
  <title>AppName</title>
</head>

<body>
  <div class="departments">
    <script type="text/template" id="department-list-template">
      <span><%= dept_desc %></span>
    </script>
  </div>
  <script>
    var departments = new DepartmentCollection();
    departments.fetch();

    var departmentList = new DepartmentListView({
      collection: departments
    });

    $('.departments').html(departmentList.render().$el);
    departmentList.render();
  </script>
</body>

</html>

标签: backbone.js
3条回答
不美不萌又怎样
2楼-- · 2019-09-05 15:57

Since you don't have an item view, I think it's best to iterate on the collection view's template. Make sure you create the view instance/call it's render after your collections fetch method succeeds.

Also, you shouldn't add your template inside an element that can be removed.

Department = Backbone.Model.extend({
  idAttribute: "dept_id",
  defaults: {
    dept_code: '',
    dept_desc: ''
  }
});

DepartmentCollection = Backbone.Collection.extend({
  model: Department
});

var DepartmentListView = Backbone.View.extend({
  template: _.template($('#department-list-template').html()),
  tagName: "ul",
  render: function() {
    this.$el.html(this.template({
      departments: this.collection.toJSON()
    }));
    return this;
  }
});
var departments = new DepartmentCollection([{
  dept_id: 1,
  dept_code: 'test1',
  dept_desc: 'test1'
}, {
  dept_id: 2,
  dept_code: 'test2',
  dept_desc: 'test2'
}]);

/*
departments.fetch({
  success: function(){
    // render the view here
  }
});
*/

var departmentList = new DepartmentListView({
  collection: departments
});

$('.departments').html(departmentList.render().$el);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<div class="departments"></div>
<script type="text/template" id="department-list-template">
  <% _.each(departments,function(deparment){ %>
    <li><span><%= deparment.dept_desc %></span></li>
  <% }); %>
</script>

查看更多
Root(大扎)
3楼-- · 2019-09-05 16:01

You are calling the render before the ajax call is finished. just use deferred and call render when fetch is finished.

Try changing html this way

<!DOCTYPE html>
<html>
<head>
    <title>AppName</title>

</head>
<body>
<script type="text/template" id="department-list-template">
    <li><%= dept_desc %></li>
</script>


<div class="departments">

</div>
<script type="text/javascript">

    var departments = new DepartmentCollection();

  var departmentList = new DepartmentListView({
    collection: departments
  });
  $.when(departments.fetch()).then(function () {
     $('.departments').html(departmentList.render().$el);
  });

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

and the view

var DepartmentListView = Backbone.View.extend({
        template: _.template($('#department-list-template').html()),
        tagName: "ul",


        render: function () {
            var results = [];

            var self = this;
            this.collection.each(function (department) {
                console.log(department);
                var html = self.template(department.toJSON());
                results.push(html);
            });

            this.$el.html(results);

            return this;
        }

    });
查看更多
我想做一个坏孩纸
4楼-- · 2019-09-05 16:19

The underscore template function accepts an html string, but you're giving it an id string. Try

var DepartmentListView = Backbone.View.extend({
  template: _.template($('#department-list-template').html()),


  tagName: "ul",

  render: function(){
    var results = [];

    this.collection.each(function(department){
    var html = this.template(department.toJSON());
    results.push(html);
    });

    this.$el.html(results);

    return this;
  }

});

EDIT: using the correct context

render: function(){
    var results = [];
    var self = this;
    this.collection.each(function(department){
    var html = self.template(department.toJSON());
    results.push(html);
    });

    this.$el.html(results);

    return this;
  }
查看更多
登录 后发表回答