【问题标题】:Use Twitter Bootstrap button group as radio select with knockout bindings使用 Twitter Bootstrap 按钮组作为带有敲除绑定的单选框
【发布时间】:2013-03-25 07:21:20
【问题描述】:

这是有效的:

view.html

<div><input type="radio" name="radioPriority" data-bind="checked: priority" value="want" style="margin-top: -3px; margin-right: 3px;" />I want to</div>
<div><input type="radio" name="radioPriority" data-bind="checked: priority" value="need"  style="margin-top: -3px; margin-right: 3px;"/>I need to</div>

controller.js

function feedbackViewModel() {
    var self = this;
    self.priority = ko.observable("want");
    //lots of other stuff
}

正如预期的那样,当您选择第二个收音机时,priority observable 的值将变为“需要”。但是,我想将 Twitter Bootstrap 按钮组用作收音机。这是我拥有的 HTML,但它并没有像预期的那样改变 observable:

<span class="btn-group" data-toggle="buttons-radio">
    <button data-bind="checked: priority" type="button" class="btn" value="want">I want to</button>
    <button data-bind="checked: priority" type="button" class="btn" value="need">I need to</button>
</span>

更新我在这里有一个 jsfiddle:http://jsfiddle.net/a8wa8/6/“priority1”是标准单选选择,“priority2”是引导按钮。

【问题讨论】:

    标签: mvvm twitter-bootstrap knockout.js durandal


    【解决方案1】:

    问题是您正在使用Checked 绑定按钮,这是不允许的,您可以使用点击绑定。检查这个小提琴:

    http://jsfiddle.net/a8wa8/7/

    更新:

    是的,您可以通过使用 ko css binding 来实现这一点。检查这个更新的小提琴:

    Updated Fiddle

    【讨论】:

    • 这很好用,只是当我更改模型时它不会更新视图。即,务实地设置priority2('want') 不会选择适当的按钮。这很容易做到吗?
    • @ScottBeeson 请检查我更新的答案,让我知道这是你想要的吗?
    • @gaurav 是否可以将 data-bind 属性的内容移动到 js 文件中?如果可能,它会是什么样子?
    • @Skytiger 为什么要将数据绑定属性移动到 js 文件?数据绑定的主要目的是将您的数据模型与您的视图模型绑定。如果您尝试将数据绑定与动态元素一起使用,则可以将绑定应用到新创建的元素,例如 ko.applyBindings(yourmodel, document.getElementById('newElementId'));
    • 好东西!我已经修改了小提琴以演示如何将模型的编程更改反映回按钮组:jsfiddle.net/yvopLvsu/1(我还修改了 JS 代码以使用 === 并添加了几个缺少的分号)
    【解决方案2】:

    checked binding 仅适用于“可检查”控件,例如复选框 (&lt;input type='checkbox'&gt;) 或单选按钮 (&lt;input type='radio'&gt;)。

    但您在第二个示例中有 button,其中引导程序只是模拟单选按钮组的外观,因此 checked 绑定不起作用。

    但是,您可以使用 click binding 将值传递给您的 observable:

    <span class="btn-group" data-toggle="buttons-radio">
         <button data-bind="click: function() { priority2('want') }" 
                 type="button" class="btn" value="want">I want to</button>
         <button data-bind="click: function() { priority2('need') }" 
                 type="button" class="btn" value="need">I need to</button>    
    </span>
    

    您可以将其隐藏在自定义绑定后面:

    ko.bindingHandlers.valueClick = {
        init: function(element, valueAccessor, allBindingsAccessor, 
                      viewModel, bindingContext) {     
            var value = valueAccessor();
            var newValueAccessor = function() {
                return function() {
                    value(element.value); 
                };
            };
            ko.bindingHandlers.click.init(element, newValueAccessor, 
                allBindingsAccessor, viewModel, bindingContext);
        },
    }
    

    然后你可以像这样使用它:

    <span class="btn-group" data-toggle="buttons-radio">
         <button data-bind="valueClick: priority2" 
                 type="button" class="btn" value="want">I want to</button>
         <button data-bind="valueClick: priority2" 
                 type="button" class="btn" value="need">I need to</button>    
    </span>
    

    演示JSFiddle.

    【讨论】:

    • 这也有效,虽然它比 gaurav 的答案复杂得多,但它也有同样的问题。这不是双向绑定。如果我设置了 priority('want') 和 priority2('want'),你会看到收音机是自动选择的,但引导按钮不是。
    • 如果您还想要双向绑定,那么您需要将clickcss 绑定结合起来。我的valueClick 自定义绑定处理程序也可以扩展来处理这种情况。起初它可能看起来很复杂,但它是更易于维护的解决方案。因为在您接受的答案中,您必须在按钮上重复“想要”和“需要”3 次以及“优先级 2”2 次。另一方面,使用自定义绑定,您需要编写一次所有内容。
    • @nemesv Duuuuude 您的解决方案非常适合我的需要。谢谢,我需要扩展valueClick 的功能来处理双向绑定,就像你说的那样,但到目前为止它是完美的。
    • @nemesv 你的例子在两个方面帮助了我;它解决了相同的按钮组问题,并向我展示了我不需要视图模型上的“切换”功能。因为 observables 是函数,你可以简单地在绑定点击事件中传递一个新值。干杯。
    猜你喜欢
    • 2015-07-30
    • 2016-03-21
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    • 2014-09-24
    • 2013-02-28
    • 2016-12-31
    • 1970-01-01
    相关资源
    最近更新 更多