javascript - Knockout + Bootstrap 3 单选按钮

标签 javascript html twitter-bootstrap knockout.js twitter-bootstrap-3

相关:Bootstrap Radio Button Group

HTML:

<div class="btn-group" data-toggle="buttons">
    <label class="btn btn-primary">
        <input type="radio" name="options" id="option1" value="1" data-bind="checked: optionsValue"> Option 1
    </label>
    <label class="btn btn-primary">
        <input type="radio" name="options" id="option2" value="2" data-bind="checked: optionsValue"> Option 2
    </label>
    <label class="btn btn-primary">
        <input type="radio" name="options" id="option3" value="3" data-bind="checked: optionsValue"> Option 3
    </label>
</div>
<br />
<span data-bind="text: optionsValue"></span>

Javascript:

var ViewModel = function() {
    this.optionsValue = ko.observable()
};

ko.applyBindings(new ViewModel());

JsFiddle:


我有上面的代码,我正在尝试按预期工作。问题是当 data-toggle="buttons" 被添加到 btn-group div(如 Bootstrap 3 example 中)时,knockout 绑定(bind)停止工作。如果我将数据切换从按钮组中移除,那么绑定(bind)将按预期工作,但按钮组看起来很糟糕。我知道这在 Bootstrap 2 中不起作用,因为他们实际上并没有将 radio 输入用于他们的 radio 样式。为什么它现在拒绝工作,即使他们工作?

最佳答案

bootstrap buttonsknockout checked绑定(bind)仍然不能很好地发挥作用:

  • knockout 使用 checked 绑定(bind)中的 click 事件触发底层可观察对象发生变化
  • bootstrap 订阅点击事件以进行切换,但会调用 e.preventDefault(),因此 KO 不会收到有关点击的通知。

一个可能的解决方案是创建一个自定义绑定(bind)处理程序,您可以在其中订阅 change 事件(这是由 toogle 上的 Bootstrap 触发的)并在那里设置您的可观察值:

ko.bindingHandlers.bsChecked = {
    init: function (element, valueAccessor, allBindingsAccessor,
    viewModel, bindingContext) {
        var value = valueAccessor();
        var newValueAccessor = function () {
            return {
                change: function () {
                    value(element.value);
                }
            }
        };
        ko.bindingHandlers.event.init(element, newValueAccessor,
        allBindingsAccessor, viewModel, bindingContext);
    },
    update: function (element, valueAccessor, allBindingsAccessor,
    viewModel, bindingContext) {
        if ($(element).val() == ko.unwrap(valueAccessor())) {
             setTimeout(function () {
                $(element).closest('.btn').button('toggle');
             }, 1); 
        }
    }
}

并在您的 View 中使用它:

<label class="btn btn-primary">
    <input type="radio" name="options" id="option1" value="1" 
           data-bind="bsChecked: optionsValue"> Option 1
</label>

使用 Bootstrap 3.0.2 的原始演示 JSFiddle .
使用 Bootstrap 3.2.0 更新了演示 JSFiddle .

关于javascript - Knockout + Bootstrap 3 单选按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20077475/

相关文章:

jquery - 更改顶部 div 高度但下方元素不会更改位置

javascript - 删除 React 中内联 block 元素之间的空格

css - 在 Twitter Bootstrap 中更改导航栏颜色

c# - 使用多个asp创建Bootstrap-Datepicker :Repeater TextBoxes

javascript - Nativescript getViewById 未更新倒计时

javascript - 需要将 .innerHTML 的结果转换为 javascript 上的数字

javascript - 使用 anchor 链接将查询字符串添加到 url

javascript - 向我的 js 生成的 "checkers"板添加一个额外的层

javascript - 如何将 anchor 链接列表转换为选择下拉列表,在选项更改时操作更改选项卡?

javascript - bootstrap.js 工具提示插件中使用的奇怪语法以及计算工具提示位置