Select2 用字符串覆盖淘汰赛 observableArray
Posted
技术标签:
【中文标题】Select2 用字符串覆盖淘汰赛 observableArray【英文标题】:Select2 overwrites knockout observableArray with string 【发布时间】:2014-10-08 10:39:27 【问题描述】:我正在使用带有自定义剔除绑定的 select2 来提供动态标记支持。不幸的是,当用户修改 select2 控件时,绑定的 observable 数组会被逗号分隔的值字符串覆盖,而不是简单地将新值添加到 observable 数组中。我猜这与我绑定输入值的方式有关,但我似乎找不到替代方法。任何帮助将不胜感激!
JSFiddle:http://jsfiddle.net/gk8a6sht/6/
ko.bindingHandlers.select2 =
init: function(element, valueAccessor)
var options = ko.toJS(valueAccessor()) || ;
setTimeout(function()
$(element).select2(options);
, 0);
;
var viewModel =
values: ko.observableArray(["red", "grey", "blue"])
;
ko.applyBindings(viewModel);
html:
<input data-bind="value: values, select2: tags: values, tokenSeparators: [',', ' '] "/>
【问题讨论】:
我已经编辑了我的答案,现在看起来好多了。我希望这是你想要的。 你检查过答案了吗?如果有帮助,你能接受吗? 【参考方案1】:编辑 2:
更正了以下代码中的 split
函数以使用指定的 tokenSeparators
。 Fiddle 也更新了。
编辑:
我已经阅读了一些关于select2 插件及其标记支持的内容。据我了解,您已经将预定义的一组标签(在选项中设置)与用户选择的实际标签混合在一起。我已经显着更新了我的jsfiddle,现在绑定处理程序如下所示:
ko.bindingHandlers.select2 =
defaults:
value: ko.observable(),
select2Options:
tags: ko.observableArray([]),
tokenSeparators: [',', ' ']
,
init: function(element, valueAccessor)
var bindingOptions = valueAccessor() || ,
options = $.extend(true, ,
ko.bindingHandlers.select2.defaults,
bindingOptions),
value = ko.utils.unwrapObservable(options.value);
$(element).val(value);
$(element).select2(ko.toJS(options.select2Options));
$(element).change(function()
options.value($(element).val().split(options.select2Options.tokenSeparators));
);
,
update: function(element, valueAccessor)
ko.utils.unwrapObservable(valueAccessor());
$(element).val(valueAccessor().value());
;
首先,为了方便起见,我添加了默认值,例如,您不必每次都指定标记分隔符。接下来,我已将标签选择的所有管道移至绑定处理程序,现在您的视图模型如下所示:
function ViewModel ()
var self = this;
self.predefinedValues= ko.observableArray();
self.selectedValues = ko.observableArray();
;
ViewModel.prototype.init = function()
// Here we should init our model with values from server, for example
this.predefinedValues(["red", "grey", "blue"]);
this.selectedValues(["red"]);
所以现在你有 2 个可观察数组 - 第一个是预定义的标签集,第二个是实际选定标签的数组。
标记如下:
<input type="hidden" style="width: 300px" data-bind="select2: value: selectedValues, select2Options: tags: predefinedValues "/>
所以没有字符串了,一切都在绑定处理程序中完成。
原答案:
只需使用另一个 observable 来保留 select2 字符串的值,如下所示:
HTML:
<input data-bind="value: selectedValuesString, select2: tags: values, tokenSeparators: [',', ' '] "/>
Javascipt:
function ViewModel ()
var self = this;
self.values= ko.observableArray(["red", "grey", "blue"]);
self.selectedValuesString= ko.observable(self.values().join(","));
self.selectedValuesString.subscribe(function(newValue)
self.values(newValue.split(','));
);
;
我已将视图模型声明从对象更改为函数,因此编写订阅函数会更容易。
您还应该在自定义绑定中使用update
函数来响应列表更改。
我已更新您的 jsfiddle 以展示其工作原理。我添加了Add value
按钮,看看它如何与添加元素一起工作。我使用了一个随机数来添加新值,因为 select2 不喜欢我猜想的相似值(将它们视为一个值)。
【讨论】:
感谢您的详细回复和解决方案。这种方法当然适用于提供的标记分隔符。依赖 'split' 函数的缺点是,如果您在标签中允许逗号,它会失败(从 tokenSeparators 数组中删除 ',' 以查看)。这更多是关于 select2 如何更新输入的问题,您可以通过一些巧妙的 JavaScript 来克服这个问题。 @mindlessgoods,哎呀,我只是忽略了这一点。请参阅编辑后的答案,我已更新 fiddle link。我想现在它值得一票;)以上是关于Select2 用字符串覆盖淘汰赛 observableArray的主要内容,如果未能解决你的问题,请参考以下文章