渲染 Backbone.js 集合

Posted

技术标签:

【中文标题】渲染 Backbone.js 集合【英文标题】:Render a Backbone.js collection 【发布时间】: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"]);
);

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

感谢您的帮助...

【问题讨论】:

【参考方案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.Marionette、Chaplin 和Layout Manager。

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

【讨论】:

以上是关于渲染 Backbone.js 集合的主要内容,如果未能解决你的问题,请参考以下文章

如何正确渲染 Backbone.js 视图

Backbone.js - 集合未定义

Backbone.js 模型与集合

Backbone.js 单个集合项视图

Backbone.js 将模型添加到集合问题

Backbone.js:在现实世界的应用程序中呈现集合