显然,在将jQuery multiselect()与Knockout.js结合使用时,Bootstrap multiselect有一个局限性,因此,如果在Knockout事件(在以下示例中为click事件)中通过代码修改了multiselect下拉列表,则不会应用该代码。

以下示例对此进行了演示:

  1. 首先,单击左侧的按钮。 您会看到尽管创建了选项,但未选中它们。 您需要再次单击才能将其选中。
  2. 然后,单击右侧的按钮。 您将看到选项已被创建和选中。 我使用了1000毫秒的超时时间,但它也仅适用于1毫秒的超时时间。

我的问题:是否有比超时更好的方法来使selectAll()工作?

 var selectorVM = function () { var self = this; self.available = ko.observableArray([]); self.selected = ko.observableArray([]); self.init = function () { self.initOptions(); self.selectAll(); }; self.initWithTimeout = function () { self.initOptions(); self.selectAllWithTimeout(); }; self.initOptions = function () { self.available([]); self.available([ { name: "option 1", value: 1}, { name: "option 2", value: 2} ]); }; self.selectAll = function () { var $selector = $("#selector"); $selector.multiselect('selectAll', false); $selector.multiselect('updateButtonText'); }; self.selectAllWithTimeout = function () { setTimeout(self.selectAll, 1000); }; } var selectorVM = new selectorVM(); ko.applyBindings(selectorVM); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-multiselect/0.9.15/js/bootstrap-multiselect.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-multiselect/0.9.15/css/bootstrap-multiselect.css" rel="stylesheet"/> <div> <button class="btn btn-default" data-bind="click: init">Click to init dropdown, no timeout</button> <button class="btn btn-default" data-bind="click: initWithTimeout">Click to init dropdown, with timeout</button> </div> <div> <select id="selector" class="form-control" multiple="multiple" data-bind="options: available, optionsText: 'name', optionsValue: 'value', selectedOptions: selected, multiselect: { includeSelectAllOption: true }"> </select> </div> 

#1楼 票数:0 已采纳

您的问题在于代码执行顺序。 内置的KO options绑定处理程序和jQuery Multiselect插件都在修改DOM,并且options处理程序可能 multiselect函数之后执行,因此在构建multiselect菜单时,尚无任何选项可供选择。 当您使用setTimeout ,即使有1ms的超时,该函数也会被推送到调用堆栈的末尾,并在当前事件循环结束时执行(请参见此处以获取更多详细信息),因此现在在options绑定完成后执行完成。 因此,它有效。

但是,这不是很漂亮。 在视图模型中执行DOM操作绝不是一个好主意。 这就是为什么自定义绑定处理程序很重要。 轻松与DOM元素进行交互并保持视图模型整洁。 您的代码引用了multiselect绑定处理程序,但是我在您的文章中没有看到它。 如果我们创建它(并不复杂),我们将看到可以使菜单按预期工作。 最初的问题是您正在使用提供的绑定处理程序以及手动操作DOM。 您应该坚持使用绑定处理程序,它将可以正常工作。 无需超时。

使用KO之类的框架,作为一般的经验法则,您总是只需要在视图模型中操纵数据即可。 KO应该尽力更新UI。 因此,如果要选择所有项目,请考虑一下它是如何工作的:存在一个称为selected的可观察数组,用于存储所选项目的ID。 因此,如果要选择所有项目,则只需要遍历所有可用项目,然后将ID推送到所选阵列。 KO将为您更新UI。 请参阅更新的代码段。 我创建了一个单独的按钮来调用selectAll函数,但是如果愿意,您当然可以在init函数中调用selectAll

 var selectorVM = function () { var self = this; self.available = ko.observableArray([]); self.selected = ko.observableArray([]); self.init = function () { self.initOptions(); }; self.initOptions = function () { self.available([ { name: "option 1", value: 1 }, { name: "option 2", value: 2 } ]); }; self.selectAll = function () { self.available().forEach(function (opt) { if (self.selected.indexOf(opt.value) === -1) { self.selected.push(opt.value); } }); } } var selectorVM = new selectorVM(); ko.applyBindings(selectorVM); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-multiselect/0.9.15/js/bootstrap-multiselect.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-multiselect/0.9.15/css/bootstrap-multiselect.css" rel="stylesheet"/> <div> <button class="btn btn-default" data-bind="click: init">Click to init dropdown, no timeout</button> <button class="btn btn-default" data-bind="click: selectAll">Select all</button> </div> <div> <select id="selector" class="form-control" multiple="multiple" data-bind="options: available, optionsText: 'name', optionsValue: 'value', selectedOptions: selected, multiselect: { includeSelectAllOption: true }"> </select> </div> <p>Selected options in observable array:</p> <ul data-bind="foreach: selected"><li data-bind="text: $data"></li></ul> 

  ask by HeyJude translate from so

未解决问题?本站智能推荐:

1回复

引导程序选择的剔除自定义绑定不会更新视图模型“selectedCategories/selectedCategory”

我正在创建一个淘汰赛js自定义绑定,它将允许我将数据绑定与bootstrap multiselect一起使用 。 我需要它可以用于单个<select> ,也可以用于multiselects <select multiple="true"> 。 我在这个jsfiddle
1回复

我的使用引导多重选择的下拉列表没有填充

我正在尝试使用引导javascript和CSS文件创建多选下拉列表。 不幸的是,我动态创建的一组选项(使用AJAX)似乎没有填充列表。 我知道它必须与多选功能有关,因为当我将其设置为单选下拉列表时,它的效果很好。 我想知道它是否与何时调用此函数有关。 当文档准备就绪时,不调用列表,而
2回复

即使在引导多重选择中也如何处理onclick?

我有一个下拉列表,我为此添加了bootstrap multiselect。 我这样添加了多选, 在bootstrap multiselect中,他们有自己的全选选项,我不想在这里使用它。 我想要“全选”逻辑,将选择切换到“ opt8”。 请帮忙。
1回复

剔除引导程序未加载

我有一个基于基因敲除网站。 我有一个标签输入字段和一个多重选择元素。 如果它们显示在负载下,所有工作正常。 但是我只想在用户单击按钮时显示它们。 我怎样才能做到这一点? 谢谢
2回复

基于jQuery中的数据属性选择引导多重选择中的值

我是jquery / bootstrap编码的新手,想实现以下目标。 我有一个选择(使用引导程序多选)和几个选项。 在此列表中,我尝试选择与数组值匹配的所有选项(下面的代码中的list1)。 但是,我不需要查看选项的op值,而是需要检查选项的数据属性(以下代码中的清单2)。 我的下拉菜
2回复

如何设置引导多重选择最小选定值和最大选定值

我有5个选项的多选下拉列表。 我希望用户一次可以选择最多3个选项,一次可以选择最小1个选项,该怎么做? 我的代码就是这样
1回复

AngularJS:使用多重选择预先输入Bootstrap

我在我的角度应用程序中使用bootstrap multiselect。 (引导程序2.3) http://davidstutz.github.io/bootstrap-multiselect/index-2-3.html#examples 我想将相同的内容转换为提前引导,但用户仍然可以
1回复

多重选择在每次提交后取消选择最后一项

每次$_POST提交后,多选减少,但是返回所有ajax响应索引。 在这种形式下,我有一个事件会触发Empresa中的更改,该更改会加载所有其他字段并标记ajax返回的php会话中的选项。 每次提交后,我拥有会话的所有项目,但始终取消选择每个字段上的最后一个项目。