javascript - Backbone/Marionette div 包装器干扰选择选项

标签 javascript backbone.js marionette

我有一个布局 View ,其中一个区域包含选择输入。

//template
<div class="col-xs-12">
    <select name="type" id="drop" class="select"></select>
</div>

我有一个 LayoutView,它定义以下区域并分配一个 Collection View 以使用选项填充选择菜单。

//layout
Backbone.Marionette.LayoutView.extend({
    regions: {drop: "#drop"},
    onRender: function() {
        this.getRegion("drop").show(new (Marionette.CollectionView.extend({
            childView: FieldView
        }))(collection: fieldCollection)));
    }
}

FieldViewfieldCollection 工作正常,但我有一个问题。渲染时,集合 subview 将选项包装在 div 标记中,从而导致选择菜单无法正常工作。

//Rendered HTML
<select name="type" id="drop" class="select">
    <div>
        <option value='1'>Option 1</option>
        <option value='2'>Option 2</option>
        <option value='3'>Option 3</option>
    </div>
</select>

关于如何摆脱那个讨厌的 div 标签有什么建议吗?并且 subview 的 el 不应该根据区域的作用范围限定为 select 元素本身吗?

最佳答案

由于您的问题是一个很常见的问题,因此额外的 div 功能经常引起争议。例如,看看这个非常有趣的 issue

不幸的是,Backbone 和 Marionette View 都知道它们的父 View ,即使该父 View 是 LayoutView。事实上,Marionette 继承了 Backbone 的包装器行为,并且在大多数情况下,它是 View 所具有的最常识性的结构。

更改 CollectionView el ,危险地生活

您可以采取更危险的路线,将 Region 的元素分配给 CollectionView 的 el ,我在 Answer 中对此进行了描述。我的建议是覆盖该区域的 .attachHtml()方法将 subview 的内容(而不是 el )直接插入到 el 中区域的,,最重要的是,设置 subview 的 el至该地区的el使用view.setElement() 。但请仔细阅读那里的警告。两个 View 之间的事件将共享!这是你无法避免的。

拥抱包装器,拥抱 Backbone

就我个人而言,我主张在这方面与 Backbone/Marionette 合作,而不是反对。我知道您可能有充分的理由想要 <select/> LayoutView 中的元素。 但是,如果您可以在没有该元素的情况下生活,我可以为您提供一个非常简单且快速的解决方案:您可以使用您想要的任何(适当的)HTML 元素作为 View 的包装器。所以你的.show()看起来像这样:

onRender: function() {
  this.getRegion("drop").show(new (Marionette.CollectionView.extend({
    tagName: "select",
    attr: {
      name:"type"
    },
    id: "drop", 
    className: "select",
    childView: FieldView
  }))(collection: fieldCollection)));
}

我在那里所做的只是改变了 Vanilla <div/> el View ,到

<select name="type" id="drop" class="select"></select>

不要忘记,您需要为您的区域分配一个新元素。我们来看看原版<div/>附上 <select/> ,例如,

<div class="col-xs-12" id="field-region">

</div>

访问<select/> LayoutView 中的元素

<select/>声明不是 el您的 CollectionView 的。这可能不会打扰您,但很可能在某些时候您会做类似 $("#drop").val() 的事情在你的布局 View 中。好消息是您可以 native 访问 <select/>因为它是el您传入的 CollectionView 的属性。代价是您需要保留该 View 的引用。比如,

onRender: function() {
  this.fieldView = new Marionette.CollectionView.extend({
    tagName: "select",
    attr: {
      name:"type"
    },
    id: "drop", 
    className: "select",
    childView: FieldView
  });
  this.getRegion("drop").show(this.fieldView(collection: fieldCollection));
},

onSelectOption: function () {
  console.log(this.fieldView.$el.val());
}

关于javascript - Backbone/Marionette div 包装器干扰选择选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28530261/

相关文章:

javascript - 如何使用作为参数传递的属性名称?

javascript - 将两个 javascript 调用合并为一个涉及 GET 请求的调用

javascript - Lodash 比较/合并对象与数组

javascript 无法检测数组中的相同元素

javascript - 如何删除 Backbone 模型

javascript - D3.js 表附加相同的数据值

javascript - 将多个属性更改绑定(bind)到 Backbone.js 模型的正确方法

backbone.js - 如果没有获取模型,如何防止 Backbone.Marionette 渲染 View ?

javascript - 如何访问 Collection View (或布局)的 templateHelper 中的特定模型?

backbone.js - 在 Backbone Marionette 和 Relational 中使用复合 View