使用bootstrap按钮组复选框绑定的正确方法是什么?

时间:2016-06-14 21:06:43

标签: javascript twitter-bootstrap knockout.js knockout-3.0 buttongroup

checked属性未检查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&amp;&amp; TUE为false,但UI未显示星期一已检查。当我手动检查时,它也不会更新isChecked observable。

1 个答案:

答案 0 :(得分:0)

data-tobble="buttons"位对KnockoutJS不起作用,因为Bootstrap内部将处理click上的label并通过双切换来执行preventDefault复选框。

This other question几乎是重复的,但由于某些原因,我无法从那里的答案( 可能是最合适的方法)中获得自定义绑定处理程序具体情况。这就是为什么我在这里发布一个单独的答案。

当前情况的解决方法是明确摆脱input元素。因为您正在使用KnockoutJS,这可能/可能不是一个大问题,因为您通常会将序列化视图模型发布到您的后端(并且不依赖于带有输入的html表单)。如果您这样做,您可以通过以下方式解决:

  1. 使用click处理程序(看起来比下面更清晰,例如视图模型构造函数);
  2. 最初自己设置.active (初始状态应由用户代码according to the docs设置);
  3. 这是一个演示:

    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>