将JSON导入Backbone中的下划线模板

时间:2013-01-29 06:31:28

标签: json backbone.js underscore.js

刚刚开始使用Backbone并且仍然能够理解这些细节。

我试图使用Underscore和Backbone简单地显示一些JSON。我能够使用Underscore和$ .getJSON使其工作,但是当我尝试使用Backbone连接时,我会遇到各种错误,具体取决于我的尝试。

我也能够通过将值硬编码到模型中来使Backbone工作,但是当我尝试将它们整合在一起时,我正在跑到墙上。任何帮助表示赞赏。

这是我的下划线模板:

<script type="text/html" id='trailTemplate'>

    <% _.each(trails,function(trail){ %>

        <%= trail.trailname %><br />

    <% }); %>

</script>

这是我的Backbone代码:

var Trail = Backbone.Model.extend({
    urlRoot: "trails.json"
});

var trail = new Trail({});

var TrailView = Backbone.View.extend({
    el: '.page',

    template: _.template($("#trailTemplate").html(), {trails:trail.fetch()}),

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

var trailView = new TrailView({
    model: trail
});

trailView.render();

如果你需要它,这里是trails.json

[
        {
            "trailhead": "Bear Lake",
            "trailname": "Bear Lake",
            "distance": ".5",
            "gain": "20",
            "level": "easy"
        },

        {
            "trailhead": "Bear Lake",
            "trailname": "Nymph Lake",
            "distance": ".5",
            "gain": "225",
            "level": "fairly easy"
        }
]

1 个答案:

答案 0 :(得分:6)

您的trails.json文件包含一个包含2个对象的数组,这两个对象都代表一个“Trail”。所以你应该有一个集合'Trails'而不是单个模型

var Trails = Backbone.Collection.extend({
  url: '/trails.json'
});

var trails = new Trails();

下划线template function可以两种方式使用:

  1. _。template(templateString) - 将templateString编译为可在必要时评估的函数
  2. _。template(templateString,data) - 使用给定数据编译并立即评估模板
  3. 现在你使用的方式是数字2(你声明模板的方式)和数字1(你如何在渲染中使用它)。我们来看一下模板声明:

    template: _.template($("#trailTemplate").html(), {trails:trail.fetch()})
    

    这一切都很好,直到你试图给它data - 属性。首先此时不需要提供数据,您只想创建可在View呈现时评估的模板函数。其次,你想要传递给data的东西完全不是你想象的那样。

    trail.fetch()不返回获取结果,它返回使用fetch进行的ajax调用的ajax句柄。值得庆幸的是Backbone是这样的,所以你不必考虑所有这些痛苦的ajax东西,而是你可以信任Backbone发出的事件。因此请点击Backbone Catalog o' Events并查看reset

      

    “重置”(集合,选项) - 当集合的全部内容被替换时。

    这是你的集合将在fetch之后发出的事件(我认为也是sync)。在发出此事件之前,您的集合将为空,因此在听到此reset事件之前,无需执行任何操作。所以现在让我们把它们放在一起:

    var TrailView = Backbone.View.extend({
      el: '.page',
    
      template: _.template($("#trailTemplate").html()), // no data attribute here
    
      initialize: function() {
        this.collection.on('reset', this.render);  // render after collection is reset
        this.collection.fetch();  // fetch the collection from the trails.json file
      }
    
      render: function(){
        // evaluate the template here
        this.$el.html(this.template(this.collection.toJSON())); 
        return this;
      }
    });
    
    var trailView = new TrailView({
      collection: trails
    });
    
    // trailView.render(); <- No need for this, because it will render itself
    

    希望这有帮助!