把手不会越过我的Backbone.js Collection

时间:2014-02-09 01:13:37

标签: javascript json backbone.js handlebars.js

我有一个Backbone应用程序,我正在尝试使用JSON文件填充集合。我想从JSON生成一个“标题”列表,最终变成一个菜单。 一切进展顺利,除了Handlebars不会循环(每个)我的集合以呈现列表。

相关观点:

var MenuView = Backbone.View.extend({

template: Handlebars.compile(
    '<ul>' +  
    '{{#each items.models}}<li>{{attributes.title}}</li>{{/each}}' +
    '</ul>'
),

initialize: function  () {
    this.listenTo(this.collection, "reset", this.render);
},   

render: function () {
    this.$el.html(this.template(items));
    return this;
}

});

模型和集合:

var Magazine = Backbone.Model.extend({
urlRoot:"/items",
defaults: {
    id: '',
    title: '',
    pubDate: '1/1',
    image: ''
}
});
var MagazineMenu= Backbone.Collection.extend({
    comparator: 'title',
    model: Magazine,
    url: "/items"
});

路由器:

var MagazineRouter = Backbone.Router.extend({
routes: {
   "" : "listPage",
   "titles/:id" : "showTitle"
}, 
initialize: function  () {
    this.magazineModel = new Magazine();
    this.magazineModel.fetch();


    this.magazineView = new MagazineView({
        model: this.magazineModel
    });

    this.magazineCollection = new MagazineMenu();
    this.magazineCollection.fetch();

    this.menuView = new MenuView({collection: this.magazineCollection});
},

showTitle: function(id) {

    this.magazineModel.set("id", id);
    $("#theList").html(this.magazineView.render().el);
},

listPage : function() {
    $('#theList').html(this.menuView.render().el);
}
});

var router = new MagazineRouter();

$(document).ready(function() {
    Backbone.history.start(); 
});

最后是JSON:

[
{
    "id": "screamingzebras",
    "url": "screamingzebras",
    "title": "Screaming Zebras",
    "pubDate": "2/1",
    "image": "screamingzebras.jpg"
},
{
    "id": "carousellovers",
    "url": "carousellovers",
    "title": "Carousel Lovers",
    "pubDate": "3/1",
    "image": "carousellovers.jpg"
},
{
    "id": "gardenstatuary",
    "url": "gardenstatuary",
    "title": "Garden Statuary",
    "pubDate": "4/1",
    "image": "gardenstatuary.jpg"
},
{
    "id": "sombreromonthly",
    "url": "sombreromonthly",
    "title": "Sombrero Monthly",
    "pubDate": "1/1",
    "image": "sombreromonthly.jpg"
}
]

当我在浏览器中运行它时,我在控制台中没有错误。如果我在视图中调用console.log(this.collection)之前this.$el.html(this.template(items));,我可以看到具有从JSON正确填充的models属性的集合。 当我查看Chrome开发工具中的“元素”面板时,我发现它生成的所有内容都包括<ul>标记。这让我相信我只是错过了一个关键逻辑点,即让Handlebars的每个函数实际循环遍历集合。

1 个答案:

答案 0 :(得分:0)

我在这里看到两个问题:

  1. items未在任何地方定义,因此render确实在说this.template(undefined)
  2. 即使您确实有一个名为items的局部变量,您的Handlebars模板也不会知道您已将其称为items,因此它不会知道{{#each items.models}}应该是迭代器过了它。
  3. 大概你的items应该是视图的this.collection,而你的render看起来应该更像这样:

    render: function () {
        this.$el.html(this.template(this.collection));
        return this;
    }
    

    这应解决问题 1 。您可以通过两种方式解决问题 2

    1. 更改模板以引用正确的内容。
    2. 更改您致电this.template的方式,以便items与正确的事物相关联。
    3. 第一个选项将使用上面的render和一个如下所示的模板:

      <ul>
          {{#each models}}
              <li>{{attributes.title}}</li>
          {{/each}}
      </ul>
      

      第二个选项会保留您的模板,但更改render以使用:

      this.$el.html(
          this.template({
              items: this.collection
          })
      );
      

      另一种选择是使用this.collection.toJSON()向模板提供数据,然后render将使用:

      this.$el.html(
          this.template({
              items: this.collection.toJSON()
          })
      );
      

      然后模板将是:

      <ul>
          {{#each items}}
              <li>{{title}}</li>
          {{/each}}
      </ul>