【问题标题】:Render a Backbone.js collection渲染 Backbone.js 集合
【发布时间】:2011-12-19 01:56:31
【问题描述】:

我是 Backbone.js n00b 并试图了解它。我知道如何使用视图和内置的 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"}]);
});

它在视图中的模板属性行上中断,但我不确定那是我需要查看的地方。我应该渲染一个集合还是在这里完全忽略了要点(也许集合只是对对象进行分组,我不应该将其视为可以渲染的列表)?

感谢您的帮助...

【问题讨论】:

    标签: collections backbone.js render


    【解决方案1】:

    问题在于,当您定义 ContinentsView 时,会评估模板并使用 $('#continents-template') - 但 DOM 尚未准备好,因此找不到模板。

    要解决它,只需在初始化函数中移动模板赋值即可:

    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});
    });
    

    【讨论】:

    • 谢谢迪拉!该模板现在确实可以工作,并且模型不应该知道的关于视图的提示确实很有帮助。 reset 似乎仍然没有触发视图渲染功能。有什么想法吗?
    • 抱歉,知道了,我必须将您示例中的最后 2 行改掉。我必须在 重置集合之前初始化大洲视图。谢谢!
    • @dira +1 非常感谢您指出模型/集合不应引用视图(至少直接引用)。一时间,我的眼睛在流血。 :)
    【解决方案2】:

    还值得注意的是,在视图中渲染集合时,还有一些额外的复杂性很快就会引起人们的注意。例如,当从集合中添加或删除模型时,通常需要重新渲染视图。实施您自己的解决方案并不是火箭科学,但可能值得研究现有解决方案,因为那里有很多经过尝试和测试的解决方案。

    Backbone.CollectionView 是一个强大的集合视图类,它处理响应鼠标点击选择模型、基于拖放对集合重新排序、过滤可见模型等。

    一些建立在主干之上的流行框架也提供简单的集合视图类,例如Backbone.MarionetteChaplinLayout Manager

    尽管 Backbone 本身并没有提供任何用于渲染集合的结构,但这是一个不平凡的问题,很多人对how it should be done 有不同的看法。幸运的是,这是一种普遍的需求,生态系统中已经有很多不错的选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-09
      • 2016-05-19
      • 2013-07-10
      • 1970-01-01
      • 2014-06-13
      相关资源
      最近更新 更多