Backbone.js 如何在DOM之外的主干木偶视图中使用Select2

Backbone.js 如何在DOM之外的主干木偶视图中使用Select2,backbone.js,marionette,backbone-views,jquery-select2,Backbone.js,Marionette,Backbone Views,Jquery Select2,我正在尝试将Select2小部件与主干木偶视图集成。我的简单设置使用一个Marionette.CollectionView来创建和处理select标记,并使用Marionette.ItemView来呈现选项标记 基本上是这样的: SelectCollectionView = Backbone.Marionette.CollectionView.extend({ itemView : SelectItemView, tagName : "select", onRender : fun

我正在尝试将Select2小部件与主干木偶视图集成。我的简单设置使用一个Marionette.CollectionView来创建和处理select标记,并使用Marionette.ItemView来呈现选项标记

基本上是这样的:

SelectCollectionView = Backbone.Marionette.CollectionView.extend({
  itemView : SelectItemView,
  tagName : "select",

  onRender : function() {
    this.$el.select2();
  },

  onClose : function() {
    this.$el.select2("destroy");
  }
}

SelectItemView = Backbone.Marionette.ItemView.extend({
  tagName : "option",

  render : function() {
    // create the needed option tags
  }
}
如您所见,我必须在呈现和关闭时调用Select2 initialize和destroy方法,以便将所需的附加标记添加到DOM中

只要处理select标记的视图(SelectCollectionView)已经添加到DOM中,这个设置就可以正常工作。如果不是这样,Select2的附加标记就会丢失,因为它们不是SelectCollectionView的$el的一部分,因此不会添加到DOM中


我想知道如何优雅地解决这个问题?可以添加一个额外的div容器并呈现其中的所有内容,但这将为脚本和DOM生成额外的代码。这也使得我的观点不那么通用。我只是希望有一个我没有想到的更好的解决办法

正如您所怀疑的,您需要一个包含div的文件来包围您的模板。幸运的是,这真的很简单。而不是您当前拥有的:

SelectCollectionView = Backbone.Marionette.CollectionView.extend({
  tagName : "select"
去掉标记名,在模板中(我假设你使用手柄或下划线或类似的东西)定义你的HTML:

template.html
木偶将自动在
周围环绕一个div,然后select2添加的所有额外标记将安全地包含在视图的
$el

我花了一些时间才弄明白,但我过去常常这样解决:

    var Select2View = Mn.View.extend({
      template: _.template('<select class="form-control"><option></option></select>'),

      onRender:function() {
        this.$el.find('select').select2();
      }
    });
选择元素内部的select标记。但在我的示例中,我不使用集合视图。如果需要获取数据,可以使用:

this.$el.find('select').select2({data: ['1','2','3','4']});

select2还提供了非常好的API,用于在运行时操作select项。

我不明白,您使用的是onRender,因此select和all选项元素已经呈现并添加到dom中。为什么你的解决方案不起作用?@Luke在主干上调用render()只会将视图渲染为当前el。该el可能只存在于内存中,不需要连接到DOM。这给许多依赖于在DOM中工作的小部件带来了问题,这也是我选择Select2而不是Select2的原因之一。您是否尝试过使用
onShow
而不是
onRender
    var Select2View = Mn.View.extend({
      template: _.template('<select class="form-control"><option></option></select>'),

      onRender:function() {
        this.$el.find('select').select2();
      }
    });
this.$el.find('select').select2();
this.$el.find('select').select2({data: ['1','2','3','4']});