我的html中有以下select
:
<select class="form-control" data-bind="multiSelectCommaSeparated: CityIds, options: $root.Cities, optionsText: 'CityName', optionsValue: 'CityId', valueUpdate: 'change'" multiple="true"></select>
我正在尝试编写一个敲除自定义绑定,以便在用户在多选下拉列表中选择多个城市时,使用逗号分隔值更新CityIds
observable。例如,如果我有以下select
:
<select id="cities" multiple="multiple">
<option value="1">City 1</option>
<option value="2">City 2</option>
<option value="3">City 3</option>
<option value="4">City 4</option>
</select>
并且用户选择前3个城市,然后我的observable应该有1,2,3
。如果用户取消选择City 3
,则观察结果应为1,2
,这应该在用户选择/取消选择select
中的任何值时立即发生。
我使用this问题引用
编写了以下自定义绑定ko.bindingHandlers.multiSelectCommaSeparated = {
init: function (element, valueAccessor) {
var selMulti = $.map($(element.id + " option:selected"), function (el, i) {
return $(el).text();
});
valueAccessor(selMulti);
},
update: function (element, valueAccessor) {
var selMulti = $.map($(element.id + " option:selected"), function (el, i) {
return $(el).text();
});
valueAccessor(selMulti);
}
}
在上面的自定义绑定中,当我更改multi select dropdown
中的选择时,不会触发更新事件。我应该在自定义绑定中更改哪些内容以实现我的要求?
答案 0 :(得分:5)
我不是直接回答回答你的问题,其他人(甚至我)也可以单独回答。相反,让我提出另一种处理方法,即恕我直言,更适合Knockout的MVVM风格。
构建视图模型以将所需的CSV字符串保存为computed observable。例如:
var ViewModel = function() {
var self = this;
self.Cities = [
{CityId: 1, CityName: "City 1"},
{CityId: 2, CityName: "City 2"},
{CityId: 3, CityName: "City 3"},
{CityId: 4, CityName: "City 4"}
];
self.SelectedCities = ko.observableArray([]);
self.SelectedCitiesCsv = ko.computed(function(){
return self.SelectedCities().join(",");
});
};
您可以使用此视图进行测试:
<select class="form-control"
data-bind="selectedOptions: SelectedCities,
options: $root.Cities,
optionsText: 'CityName',
optionsValue: 'CityId',
valueUpdate: 'change'"
multiple="true"></select>
<hr />
CSV: <p data-bind="text: SelectedCitiesCsv"></p>
请参阅this fiddle了解演示。
此方法优于自定义绑定的优点包括:
如果您没有为viewmodel使用构造函数,而是使用普通的javascript对象,则必须在创建具有基本属性的对象后添加计算的observables 。像这样:
var viewModel = {
Cities :[
{CityId: 1, CityName: "City 1"},
{CityId: 2, CityName: "City 2"},
{CityId: 3, CityName: "City 3"},
{CityId: 4, CityName: "City 4"}
],
SelectedCities : ko.observableArray([])
};
viewModel.SelectedCitiesCsv = ko.computed(function(){
return viewModel.SelectedCities().join(",");
});
或者查看this modified fiddle。