使用 bootstrap 按钮组复选框绑定选中的正确方法是什么?
What is the proper way to bind checked with bootstrap button group checkbox?
选中的 属性 没有选中 UI。
HTML
<div id="dayGroup" data-bind="foreach: dowArr" class="btn-group input-group input-append" data-toggle="buttons">
<label class="btn btn-primary">
<input type="checkbox" data-bind="checked: isChecked, value: day" autocomplete="off"/>
<span data-bind="text: day"></span>
<span data-bind="text: isChecked"></span>
</label>
</div>
JS
vm.dowArr.push({ day: 'MON', dow: 1, isChecked: ko.observable(true) });
vm.dowArr.push({ day: 'TUE', dow: 2, isChecked: ko.observable(false) });
跨度显示我期望的值,即 MON true && TUE false,但 UI 未显示已选中的星期一。当我手动检查它时,它也不会更新 isChecked observable。
data-tobble="buttons"
位不适合 KnockoutJS,因为 Bootstrap 内部将处理 label
上的 click
并执行 preventDefault
双击复选框。
This other question 几乎是重复的,尽管出于某种原因我无法从那里的答案中获得自定义绑定处理程序( 是 可能是最合适的方法) 适用于您的特定场景。这就是我 post 在这里单独回答的原因。
针对您当前情况的解决方法是直接删除 input
元素。因为您使用的是 KnockoutJS,所以这 probably/perhaps 不是什么大问题,因为您通常 post 将视图模型序列化到后端(并且不依赖 html 带有输入的表单).如果这样做,您可以通过以下方式解决:
- 使用
click
处理程序(看起来比下面更清晰,例如视图模型构造函数);
- 自己初始设置
.active
(初始状态由用户代码设置according to the docs);
这是一个演示:
var vm = { dowArr: ko.observableArray([]) };
vm.dowArr.push({ day: 'MON', dow: 1, isChecked: ko.observable(true) });
vm.dowArr.push({ day: 'TUE', dow: 2, isChecked: ko.observable(false) });
ko.applyBindings(vm);
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<div id="dayGroup" data-bind="foreach: dowArr" class="btn-group input-group input-append" data-toggle="buttons">
<label class="btn btn-primary"
data-bind="click: function() { $data.isChecked(!$data.isChecked()); },
css: { active: isChecked }">
<span data-bind="text: day"></span>
<span data-bind="text: isChecked"></span>
</label>
</div>
<hr>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
选中的 属性 没有选中 UI。
HTML
<div id="dayGroup" data-bind="foreach: dowArr" class="btn-group input-group input-append" data-toggle="buttons">
<label class="btn btn-primary">
<input type="checkbox" data-bind="checked: isChecked, value: day" autocomplete="off"/>
<span data-bind="text: day"></span>
<span data-bind="text: isChecked"></span>
</label>
</div>
JS
vm.dowArr.push({ day: 'MON', dow: 1, isChecked: ko.observable(true) });
vm.dowArr.push({ day: 'TUE', dow: 2, isChecked: ko.observable(false) });
跨度显示我期望的值,即 MON true && TUE false,但 UI 未显示已选中的星期一。当我手动检查它时,它也不会更新 isChecked observable。
data-tobble="buttons"
位不适合 KnockoutJS,因为 Bootstrap 内部将处理 label
上的 click
并执行 preventDefault
双击复选框。
This other question 几乎是重复的,尽管出于某种原因我无法从那里的答案中获得自定义绑定处理程序( 是 可能是最合适的方法) 适用于您的特定场景。这就是我 post 在这里单独回答的原因。
针对您当前情况的解决方法是直接删除 input
元素。因为您使用的是 KnockoutJS,所以这 probably/perhaps 不是什么大问题,因为您通常 post 将视图模型序列化到后端(并且不依赖 html 带有输入的表单).如果这样做,您可以通过以下方式解决:
- 使用
click
处理程序(看起来比下面更清晰,例如视图模型构造函数); - 自己初始设置
.active
(初始状态由用户代码设置according to the docs);
这是一个演示:
var vm = { dowArr: ko.observableArray([]) };
vm.dowArr.push({ day: 'MON', dow: 1, isChecked: ko.observable(true) });
vm.dowArr.push({ day: 'TUE', dow: 2, isChecked: ko.observable(false) });
ko.applyBindings(vm);
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<div id="dayGroup" data-bind="foreach: dowArr" class="btn-group input-group input-append" data-toggle="buttons">
<label class="btn btn-primary"
data-bind="click: function() { $data.isChecked(!$data.isChecked()); },
css: { active: isChecked }">
<span data-bind="text: day"></span>
<span data-bind="text: isChecked"></span>
</label>
</div>
<hr>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>