Backbone/Marionette div 包装器干扰 Select 选项
Backbone/Marionette div wrapper interfering with Select Options
我有一个布局视图,其中一个区域包含 select 输入。
//template
<div class="col-xs-12">
<select name="type" id="drop" class="select"></select>
</div>
我有一个 LayoutView,它定义了以下区域并分配了一个集合视图以使用选项填充 select 菜单。
//layout
Backbone.Marionette.LayoutView.extend({
regions: {drop: "#drop"},
onRender: function() {
this.getRegion("drop").show(new (Marionette.CollectionView.extend({
childView: FieldView
}))(collection: fieldCollection)));
}
}
FieldView
和 fieldCollection
工作正常,但我遇到了问题。渲染时,集合子视图将选项包装在 div 标记中,从而阻止 select 菜单正常工作。
//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 标签有什么建议吗?子视图的 el
不应该根据区域限制在 select 元素本身吗?
由于您的问题很常见,因此经常会争论额外的 div 功能。例如,参见这个非常有趣的 issue。
不幸的是,Backbone 和 Marionette 视图都知道它们的父视图,即使该父视图是 LayoutView。事实上,Marionette 继承了 Backbone 的包装器行为,并且在大多数情况下,它是视图具有的最常识性结构。
改变 CollectionViewel
,危险地生活
您可以采取更危险的方式,将您的区域元素分配给 CollectionView 的 el
,我在这篇 Answer 中对此进行了描述。我在那里的建议是覆盖区域的 .attachHtml()
方法,将子视图的内容(而不是 el
)直接插入区域的 el
,和,最重要的是,使用view.setElement()
将子视图的el
设置为区域的el
。但请仔细阅读那里的警告。两个视图之间的事件将共享!你无法避免。
拥抱包装纸,拥抱Backbone
就我个人而言,我提倡与合作,而不是反对Backbone/Marionette。我知道您可能有充分的理由想要在 LayoutView 中使用 <select/>
元素。 但是,如果你可以在没有那个元素的情况下生活,我可以为你提供一个非常简单快速的修复方法:你可以使用你想要的任何(适当的)HTML 元素视图的包装器。所以你的 .show()
可以看起来像这样:
onRender: function() {
this.getRegion("drop").show(new (Marionette.CollectionView.extend({
tagName: "select",
attr: {
name:"type"
},
id: "drop",
className: "select",
childView: FieldView
}))(collection: fieldCollection)));
}
我所做的只是将视图的香草 <div/>
el
更改为
<select name="type" id="drop" class="select"></select>
别忘了,您需要为您的区域分配一个新元素。让我们以包含 <select/>
的原始 <div/>
为例,
<div class="col-xs-12" id="field-region">
</div>
访问 LayoutView 中的 <select/>
元素
<select/>
语句不是您的 CollectionView 的 el
。这可能不会打扰您,但有时您可能会在 LayoutView 中执行类似 $("#drop").val()
的操作。好消息是您可以本地访问 <select/>
,因为它是您传入的 CollectionView 的 el
。代价是您需要保留对该视图的引用。像,
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());
}
我有一个布局视图,其中一个区域包含 select 输入。
//template
<div class="col-xs-12">
<select name="type" id="drop" class="select"></select>
</div>
我有一个 LayoutView,它定义了以下区域并分配了一个集合视图以使用选项填充 select 菜单。
//layout
Backbone.Marionette.LayoutView.extend({
regions: {drop: "#drop"},
onRender: function() {
this.getRegion("drop").show(new (Marionette.CollectionView.extend({
childView: FieldView
}))(collection: fieldCollection)));
}
}
FieldView
和 fieldCollection
工作正常,但我遇到了问题。渲染时,集合子视图将选项包装在 div 标记中,从而阻止 select 菜单正常工作。
//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 标签有什么建议吗?子视图的 el
不应该根据区域限制在 select 元素本身吗?
由于您的问题很常见,因此经常会争论额外的 div 功能。例如,参见这个非常有趣的 issue。
不幸的是,Backbone 和 Marionette 视图都知道它们的父视图,即使该父视图是 LayoutView。事实上,Marionette 继承了 Backbone 的包装器行为,并且在大多数情况下,它是视图具有的最常识性结构。
改变 CollectionViewel
,危险地生活
您可以采取更危险的方式,将您的区域元素分配给 CollectionView 的 el
,我在这篇 Answer 中对此进行了描述。我在那里的建议是覆盖区域的 .attachHtml()
方法,将子视图的内容(而不是 el
)直接插入区域的 el
,和,最重要的是,使用view.setElement()
将子视图的el
设置为区域的el
。但请仔细阅读那里的警告。两个视图之间的事件将共享!你无法避免。
拥抱包装纸,拥抱Backbone
就我个人而言,我提倡与合作,而不是反对Backbone/Marionette。我知道您可能有充分的理由想要在 LayoutView 中使用 <select/>
元素。 但是,如果你可以在没有那个元素的情况下生活,我可以为你提供一个非常简单快速的修复方法:你可以使用你想要的任何(适当的)HTML 元素视图的包装器。所以你的 .show()
可以看起来像这样:
onRender: function() {
this.getRegion("drop").show(new (Marionette.CollectionView.extend({
tagName: "select",
attr: {
name:"type"
},
id: "drop",
className: "select",
childView: FieldView
}))(collection: fieldCollection)));
}
我所做的只是将视图的香草 <div/>
el
更改为
<select name="type" id="drop" class="select"></select>
别忘了,您需要为您的区域分配一个新元素。让我们以包含 <select/>
的原始 <div/>
为例,
<div class="col-xs-12" id="field-region">
</div>
访问 LayoutView 中的 <select/>
元素
<select/>
语句不是您的 CollectionView 的 el
。这可能不会打扰您,但有时您可能会在 LayoutView 中执行类似 $("#drop").val()
的操作。好消息是您可以本地访问 <select/>
,因为它是您传入的 CollectionView 的 el
。代价是您需要保留对该视图的引用。像,
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());
}