1

刚刚开始使用 Backbone,仍然了解其中的来龙去脉。

我正在尝试使用 Underscore 和 Backbone 简单地显示一些 JSON。我可以使用 Underscore 和 $.getJSON 使其工作,但是当我尝试将它与 Backbone 连接时,我会根据我的尝试得到各种错误。

我还能够通过将值硬编码到模型中来让 Backbone 工作,但是当我尝试将它们组合在一起时,我遇到了困难。任何帮助表示赞赏。

这是我的下划线模板:

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

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

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

    <% }); %>

</script>

这是我的主干代码:

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"
        }
]
4

1 回答 1

6

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

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

var trails = new Trails();

下划线模板功能有两种使用方式:

  1. _.template(templateString) - 将 templateString 编译成可以在必要时评估的函数
  2. _.template(templateString, data) - 使用给定数据编译并立即评估模板

现在您使用的方式是数字 2(您声明模板的方式)和数字 1(您如何在渲染中使用它)。让我们检查一下模板声明:

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

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

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

"reset" (collection, options) — 当集合的全部内容被替换时。

这是您收集后将发出的事件(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

希望这可以帮助!

于 2013-01-29T11:13:09.817 回答