Jquery KnockoutJS自定义绑定从multi-select获取逗号分隔的值
我的html中有以下Jquery KnockoutJS自定义绑定从multi-select获取逗号分隔的值,jquery,knockout.js,Jquery,Knockout.js,我的html中有以下select: <select class="form-control" data-bind="multiSelectCommaSeparated: CityIds, options: $root.Cities, optionsText: 'CityName', optionsValue: 'CityId', valueUpdate: 'change'" multiple="true"></select> 用户选择前3个城市,然后我的可观测值应该是1
select
:
<select class="form-control" data-bind="multiSelectCommaSeparated: CityIds, options: $root.Cities, optionsText: 'CityName', optionsValue: 'CityId', valueUpdate: 'change'" multiple="true"></select>
用户选择前3个城市,然后我的可观测值应该是1,2,3
。如果用户取消选择City 3
,则可观察对象应具有1,2
,并且这应在用户在select
中选择/取消选择任何值时立即发生
我使用问题中的引用编写了以下自定义绑定:
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);
}
}
在上述自定义绑定中,当我在多选下拉列表中更改选择时,更新事件不会触发。我应该如何更改自定义绑定以达到我的要求?我不是很直截了当地回答您的问题,其他人(甚至我)可能会在单独的回答中这样做。相反,让我提出另一种方法来处理这个问题,即IMHO更适合Knockout的MVVM风格
构造视图模型以将所需的CSV字符串作为一个字符串保存。例如:
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(",");
});
};
您可以使用此视图对此进行测试:
CSV:
请参见演示
与自定义绑定相比,此方法的优点包括:
- 单元可测试李>
- 不需要定制绑定李>
- Knockout使我们的CSV字符串与视图保持同步,不需要自定义代码李>
- 不需要依赖jQuery,如果可能的话,利用KO让JS不知道实际的DOM(这再次提高了可测试性)李>
如果没有为viewmodels使用构造函数,而是为普通javascript对象使用构造函数,则必须在创建具有基本属性的对象后添加计算的可观察对象。大概是这样的:
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(",");
});
或者看看。我不是很直截了当地回答你的问题,其他人(甚至我)可能会在单独的回答中这样做。相反,让我提出另一种方法来处理这个问题,即IMHO更适合Knockout的MVVM风格
构造视图模型以将所需的CSV字符串作为一个字符串保存。例如:
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(",");
});
};
您可以使用此视图对此进行测试:
CSV:
请参见演示
与自定义绑定相比,此方法的优点包括:
- 单元可测试李>
- 不需要定制绑定李>
- Knockout使我们的CSV字符串与视图保持同步,不需要自定义代码李>
- 不需要依赖jQuery,如果可能的话,利用KO让JS不知道实际的DOM(这再次提高了可测试性)李>
如果没有为viewmodels使用构造函数,而是为普通javascript对象使用构造函数,则必须在创建具有基本属性的对象后添加计算的可观察对象。大概是这样的:
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(",");
});
或者请参见。我正试图在视图模型中使用这种方法,但我面临一个问题。我已修改了您的小提琴以演示此问题:。我已经用这种格式编写了我的整个视图模型,那么是否有其他方法可以使用这种语法编写computed
observatives?在vm之外编写:ViewModel.SelectedCitiesCsv=ko.computed(function(){return ViewModel.SelectedCities().join(,“”;})代码>尽管我建议使用基于构造函数的viewmodels,如我的第一个示例中所示。您可以使用@GôTô的建议,也可以将计算出的可观测值添加到普通javascript对象中,如果您在第二步中添加它们的话。关于这方面的提示,请参阅我的答案修改。我完全同意使用基于函数的方法viewmodels@Jeroen改进后的小提琴正在工作。我只想问一个问题,哪种类型的剔除视图模型声明更好,基于函数
还是像我现在使用的普通JS对象
?如果我使用基于函数的视图模型,那么我如何引用视图模型之外的可观察对象?链接到这方面的某类文章将非常有用:)我试图在我的视图模型中使用这种方法,但我面临一个问题。我已修改了您的小提琴以演示此问题:。我已经用这种格式编写了我的整个视图模型,那么是否有其他方法可以使用这种语法编写computed
observatives?在vm之外编写:ViewModel.SelectedCitiesCsv=ko.computed(function(){return ViewModel.SelectedCities().join(,“”;})代码>尽管我建议使用基于构造函数的viewmodels,如我的第一个示例中所示。您可以使用@GôTô的建议,也可以将计算出的可观测值添加到普通javascript对象中,如果您在第二步中添加它们的话。关于这方面的提示,请参阅我的答案修改。我完全同意使用基于函数的方法viewmodels@Jeroen改进后的小提琴正在工作。我只想问一个问题,哪种类型的剔除视图模型声明更好,基于函数
还是像我现在使用的普通JS对象
?如果我使用基于函数的视图模型,那么我如何引用视图模型之外的可观察对象?链接到这方面的某种文章将非常有用:)