渲染 Backbone.js 集合

17

我是一个Backbone.js新手,正试图理解它。我知道如何使用视图和内置的underscore.js模板引擎呈现模型。现在我正在尝试呈现一个集合,这就是我卡住的地方。这里没有服务器,所以我不会远程获取任何东西,只有一个简单的带有一些JavaScript的HTML页面。

ContinentModel = Backbone.Model.extend({});

ContinentsCollection = Backbone.Collection.extend({
  model: ContinentModel,

  initialize: function () {
    this.continentsView = new ContinentsView;
    this.bind("reset", this.continentsView.render);
  }
});

ContinentsView = Backbone.View.extend({
  el: '#continents',
  template: _.template($('#continents-template').html()),

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

$(function() {
  var continentsCollection = new ContinentsCollection();
  continentsCollection.reset([{name: "Asia"}, {name: "Africa"}]);
});

在视图的模板属性行上出现了错误,但我不确定那是我需要查找的地方。我应该渲染一个集合还是完全错过了重点(也许集合只是将对象分组,我不应该将其视为可以呈现的列表)?

谢谢你的帮助...

2个回答

34
问题在于当你定义ContinentsView时,模板已经被评估并且使用了`$('#continents-template')`,但是DOM尚未准备好,所以找不到模板。
为解决此问题,只需将模板分配移至initialize函数中。
ContinentsView = Backbone.View.extend({
  el: '#continents',
  initialize: function() {
     this.template = _.template($('#continents-template').html());
  }
  ...

关于集合,它们确实是将对象分组,尤其是模型的集合。

您应该编写代码,使模型(和集合)不知道视图,而只有视图了解模型。

ContinentModel = Backbone.Model.extend({});

ContinentsCollection = Backbone.Collection.extend({
  model: ContinentModel,
  // no reference to any view here    
});

ContinentsView = Backbone.View.extend({
  el: '#continents',

  initialize: function() {
    this.template = _.template($('#continents-template').html());
    // in the view, listen for events on the model / collection
    this.collection.bind("reset", this.render, this);
  },

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

$(function() {
  var continentsCollection = new ContinentsCollection();
  continentsCollection.reset([{name: "Asia"}, {name: "Africa"}]);
  // initialize the view and pass the collection
  var continentsView = new ContinentsView({collection: continentsCollection});
});

谢谢Dira!现在模板确实可以工作了,而且模型不应该知道视图的提示真的很有帮助。不过reset似乎没有触发视图渲染函数。有什么想法吗? - Cimm
1
抱歉,我明白了,在你的示例中我必须交换最后两行代码的位置。在重置集合之前,我必须先初始化continentsView。谢谢! - Cimm
@dira +1 非常感谢您指出模型/集合不应该直接引用视图。我的眼睛一度流血。 :) - Brian Genisio

8
值得注意的是,在视图中呈现集合时会出现其他复杂性。例如,当向集合中添加或删除模型时,通常需要重新渲染视图。实现自己的解决方案并不是什么难事,但考虑到已经有许多经过试验的解决方案,因此可能值得研究现有的解决方案。 Backbone.CollectionView 是一个强大的集合视图类,可以处理响应鼠标点击选择模型、基于拖放重新排序集合、过滤可见模型等操作。
另外,几个建立在 Backbone 之上的流行框架也提供了简单的集合视图类,如 Backbone.MarionetteChaplinLayout Manager
尽管Backbone本身不提供呈现集合的结构,但这是一个非常重要的问题,很多人对其有不同的看法。幸运的是,这是一个如此普遍的需求,生态系统中已经有相当多的好选择了。请参考如何实现

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接