我使用CompositeView显示选择标记,并使用CompositeView的集合呈现选项。
OptionView = Marionette.ItemView.extend({
template: ...
tagName: "option",
}
});
SelectView = Marionette.CompositeView.extend({
template: ...
childView: OptionView,
childViewContainer: "select",
triggers: {
"change @ui.select": "do:something"
},
ui:{
select: "[ui-select]"
},
});
奇怪的是,当我尝试从包含SelectView的LayoutView中获取所选选项时,我得到了不一致的行为:
EditActivities.LayoutView = Marionette.LayoutView.extend({
template: ...
regions: ...
onChildviewDoSomething: function(view){
console.log(view.ui.select.val());
}
})
当我在浏览器上更改select标记的值时,有时记录到控制台的是选项标记的内部HTML,有时它会记录该值。这就是我的OptionView模板:
<option value="<%=id%>"><%= name %></option>
我对这种不一致的行为感到有点困惑。想法?
答案 0 :(得分:1)
我明白了。问题出在OptionView我指定tagName是“选项”。在模板中,我还有选项标记,它实际上创建了一组嵌套选项标记。这就是造成不可预测行为的原因。
我改了它,所以我的模板现在只是:
<%= name %>
我现在遇到的问题是如何设置选项标签的value属性,因为现在它会产生和选项标签,每个项目都没有值。我目前的解决方法是在视图上添加一个初始化函数,如下所示:
initialize : function (options) {
this.$el.attr("value",this.model.attributes.id);
}
但如果有更好的方法,我肯定愿意接受......
答案 1 :(得分:1)
要包含选项的value属性以及innerHTML而不必在初始化中修改内容,可以使用Backbone的属性哈希,如下所示:
SelectView = Marionette.CompositeView.extend({
tagName: 'option',
template: _.template('<%= name %>'),
attributes: function() {
return {
'value': this.model.id
};
}
});
答案 2 :(得分:0)
正如BaskingShark所提到的,属性hash可用于指定选项元素的属性。 项目视图可用于选项元素。
var OptionView = Marionette.ItemView.extend({
tagName: 'option',
attributes: function () {
return {
'value': this.model.get('id')
}
},
template: _.template('<%= name %>')
});
使用项目视图的集合视图可用于选择标记。
var SelectOptionsView = Marionette.CollectionView.extend({
childView: OptionView
});
可以在布局视图的区域内呈现集合视图,也可以在其中侦听select标记上的事件。 举个例子:http://jsfiddle.net/95g1ojwk/3/
var pills = new Backbone.Collection([{
id: '',
name: 'Choose'
}, {
id: 'illusion',
name: 'Blue'
}, {
id: 'reality',
name: 'Red'
}]);
var OptionView = Marionette.ItemView.extend({
tagName: 'option',
attributes: function () {
return {
'value': this.model.get('id')
}
},
template: _.template('<%= name %>')
});
var SelectOptionsView = Marionette.CollectionView.extend({
childView: OptionView
});
var MyLayoutView = Mn.LayoutView.extend({
ui: {
destiny: "#destiny",
choice: '#choice'
},
regions: {
"options": "#options-region",
},
events: {
'change @ui.choice': 'chosenDestiny'
},
onRender: function () {
this.showChildView('options', new SelectOptionsView({
collection: pills,
el: this.ui.choice
}));
},
chosenDestiny: function (event) {
if($(event.target).val()==='reality'){
this.ui.destiny.text('Nothing but Truth!');
} else if($(event.target).val()==='illusion'){
this.ui.destiny.text('The Story Ends!');
} else {
this.ui.destiny.text('This is your last chance!');
}
}
});
new MyLayoutView({
el: '#app',
template: '#layout-template'
}).render();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://underscorejs.org/underscore.js"></script>
<script src="http://backbonejs.org/backbone.js"></script>
<script src="http://marionettejs.com/downloads/backbone.marionette.js"></script>
<script type="text/template" id="layout-template">
<div id="options-region">
<select id="choice"></select>
</div >
<label id = "destiny" > </label>
</script>
<script type="text/template" id="image-template">
<div class = "sizer" > <img src = "http://placehold.it/<%= width %>x<%= height %>" /> </div>
</script>
<div id="app"></div>