如何使用 Backbone + 下划线模板对 select 元素进行数据绑定?
How to data-bind select elements with Backbone + Underscore templates?
假设我想使用 Underscore 模板呈现表单。按照教程,我在我的 Backbone 视图中输入了如下内容:
var CatFormView = Backbone.View.extend({
render: function () { this.$el.html(this.template(this.model.toJSON())); }
)};
在我的模板中,
<label for="cat-name">Cat name:</label>
<input id="cat-name" value="<%- catName %>" />
一切都很好,但是如果我的表单包含 select
元素怎么办?我会做类似的事情吗:
<select id="cat-breed">
<option value="siamese" <% if (catBreed === "siamese") { %> selected <% } %>>Siamese</option>
<option value="persian" <% if (catBreed === "persian") { %> selected <% } %>>Persian</option>
<option value="scottish-fold" <% if (catBreed === "scottish-fold") { %> selected <% } %>>Scottish Fold</option>
...
</select>
还是直接在模板中绑定 input
元素,然后在视图中设置 select
的值?
第一种方法看起来非常麻烦,第二种方法将数据绑定逻辑分散到多个文件中,使得 Web 应用程序的可维护性大大降低。
什么是更好的解决方案?
编辑: 循环!现在看起来很明显,但我仍然坚持将 Underscore 模板视为标记。感谢 Clémentine。
<% var _catBreeds = [['siamese', 'Siamese'], ['persian', 'Persian'], ...]; %>
<select id="cat-breed">
<% for (var i = 0; i < _catBreeds.length; i++) { %>
<option value="<%= _catBreeds[i][0] %>" <% if (catBreed === _catBreeds[i][0]) { %>
selected <% } %> >
<%- _catBreeds[i][1] %>
</option>
<% } %>
</select>
编辑 2:或者,甚至更好(并且可重复使用):
<% function options(vals, selectedVal) {
// Can be moved into a helper library and injected when compiling template
vals.forEach(function (val, i) {%>
<option value="<%- val[0] %>" <%= (val[0] == selectedVal) ? "selected" : "" %>><%- val[1] %></option> <%
});
} %>
<select id="cat-breed">
<% options([["persian", "Persian"], ...], catBreed) %>
</select>
另一种选择是为您的表单使用其他模型,例如
[
{
'id': 'cat-breed',
'type': 'select',
'values': ["siamese", "scottish-fold", "persian"]
}
]
然后调用
this.template(data_model: this.model.toJSON(), form_model:this.form_model.toJSON())
然后构建表格并使用循环回答表格。
这将使您拥有一个更通用的模板系统,不那么麻烦,但更难编码。
假设我想使用 Underscore 模板呈现表单。按照教程,我在我的 Backbone 视图中输入了如下内容:
var CatFormView = Backbone.View.extend({
render: function () { this.$el.html(this.template(this.model.toJSON())); }
)};
在我的模板中,
<label for="cat-name">Cat name:</label>
<input id="cat-name" value="<%- catName %>" />
一切都很好,但是如果我的表单包含 select
元素怎么办?我会做类似的事情吗:
<select id="cat-breed">
<option value="siamese" <% if (catBreed === "siamese") { %> selected <% } %>>Siamese</option>
<option value="persian" <% if (catBreed === "persian") { %> selected <% } %>>Persian</option>
<option value="scottish-fold" <% if (catBreed === "scottish-fold") { %> selected <% } %>>Scottish Fold</option>
...
</select>
还是直接在模板中绑定 input
元素,然后在视图中设置 select
的值?
第一种方法看起来非常麻烦,第二种方法将数据绑定逻辑分散到多个文件中,使得 Web 应用程序的可维护性大大降低。
什么是更好的解决方案?
编辑: 循环!现在看起来很明显,但我仍然坚持将 Underscore 模板视为标记。感谢 Clémentine。
<% var _catBreeds = [['siamese', 'Siamese'], ['persian', 'Persian'], ...]; %>
<select id="cat-breed">
<% for (var i = 0; i < _catBreeds.length; i++) { %>
<option value="<%= _catBreeds[i][0] %>" <% if (catBreed === _catBreeds[i][0]) { %>
selected <% } %> >
<%- _catBreeds[i][1] %>
</option>
<% } %>
</select>
编辑 2:或者,甚至更好(并且可重复使用):
<% function options(vals, selectedVal) {
// Can be moved into a helper library and injected when compiling template
vals.forEach(function (val, i) {%>
<option value="<%- val[0] %>" <%= (val[0] == selectedVal) ? "selected" : "" %>><%- val[1] %></option> <%
});
} %>
<select id="cat-breed">
<% options([["persian", "Persian"], ...], catBreed) %>
</select>
另一种选择是为您的表单使用其他模型,例如
[
{
'id': 'cat-breed',
'type': 'select',
'values': ["siamese", "scottish-fold", "persian"]
}
]
然后调用
this.template(data_model: this.model.toJSON(), form_model:this.form_model.toJSON())
然后构建表格并使用循环回答表格。
这将使您拥有一个更通用的模板系统,不那么麻烦,但更难编码。