【问题标题】:using prettyCheckable plugin with knockoutjs 2.1 checked data-binding doesn't work使用 prettyCheckable 插件和 knockoutjs 2.1 检查数据绑定不起作用
【发布时间】:2014-01-21 17:01:36
【问题描述】:

我正在使用 prettyCheckable jquery 插件使我的复选框和单选按钮看起来很漂亮,如果我使用 data-bind="checked: dateMode" 它不起作用,因为插件隐藏了实际的复选框并使其成为自己的覆盖html 来美化复选框/收音机,因此当我检查收音机或复选框并更新模型中的值时,knockoutjs 库无法识别。如果我不使用 prettyCheckable 插件,我知道我的代码可以正常工作,所以不要告诉我我的模型或数据绑定代码搞砸了。我对此进行了测试。

https://github.com/arthurgouveia/prettyCheckable

这是我的部分视图代码。

<div id="DatesChooser" class="span5 pull-left">
    <h4><i class="icon-calendar"></i>Dates</h4>
    <input type="radio" name="Date" value="All" data-label="All Available" data-bind="checked: dateMode" /><br />
    <input type="radio" name="Date" value="Range" data-label="Range" data-bind="checked: dateMode" />
    <div data-bind="visible: dateMode() == 'Range'">
        <input type="text" id="FromYear" placeholder="1970" /> to
        <input type="text" id="ToYear" placeholder="2012" /><br />
        <div id="Date-Slider" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all">
            <div id="Date-Slider-Bar" class="ui-slider-range ui-widget-header" style="left: 0%; width: 100%;"></div>
            <a class="ui-slider-handle ui-state-default ui-corner-all" href="#" style="left: 0%;"></a>
            <a class="ui-slider-handle ui-state-default ui-corner-all" href="#" style="left: 100%;"></a>
        </div>
    </div>
</div>

这是我的淘汰赛模型:

function searchVm() {
    var self = this;
    self.dateMode = ko.observable("All");
    self.startSearch = function () { alert(self.dateMode()); };
};

我像这样初始化 prettyCheckable 的东西:

$('input:checkbox').prettyCheckable();
$('input:radio').prettyCheckable();

这是代码在 prettyCheckable 插件修改后呈现的样子,注意输入样式是 'display:none':

<div id="DatesChooser" class="span5 pull-left">
    <div class="clearfix prettyradio labelright blue">
        <input type="radio" data-bind="checked: dateMode" data-label="All Available" value="All" name="Date" style="display: none;" checked="checked">
        <a class="checked" href="#"></a>
        <label for="undefined">All Available</label>
    </div>
    <br>
    <div class="clearfix prettyradio labelright blue">
        <input type="radio" data-bind="checked: dateMode" data-label="Range" value="Range" name="Date" style="display: none;">
        <a class="" href="#"></a>
        <label for="undefined">Range</label>
    </div>
    <div data-bind="visible: dateMode() == 'Range'" style="display: none;">
        <input id="FromYear" class="placeholder" type="text" placeholder="1970">
to
        <input id="ToYear" class="placeholder" type="text" placeholder="2012">
        <br>
        <div id="Date-Slider" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all">
            <div id="Date-Slider-Bar" class="ui-slider-range ui-widget-header" style="left: 0%; width: 100%;"></div>
            <a class="ui-slider-handle ui-state-default ui-corner-all" style="left: 0%;" href="#"></a>
            <a class="ui-slider-handle ui-state-default ui-corner-all" style="left: 100%;" href="#"></a>
            <div class="ui-slider-range ui-widget-header" style="left: 0%; width: 100%;"></div>
        </div>
    </div>
 </div>

【问题讨论】:

    标签: javascript jquery knockout.js


    【解决方案1】:

    Pretty Checkable 在复选框上触发 change 事件,但 Knockout 会查找 click 事件。这可以通过更改prettyCheckable.js 第 46-54 行来解决。原文:

        if (input.attr('checked') !== undefined) {
          input.removeAttr('checked').change();
        } else {
          input.attr('checked', 'checked').change();
        }
    

    改变:

        if (window.ko) {
          ko.utils.triggerEvent(input[0], 'click');
        } else {
          input.click();
        }
    

    如果你使用 jQuery 的 click 触发函数,Knockout 也不会起作用。您必须使用 Knockout 的triggerEvent,如上。

    jsFiddle:http://jsfiddle.net/mbest/4cX48/

    【讨论】:

    • 我会尽快看看。我还有另一个项目正在做,所以我会尽快尝试。
    • 这不起作用。有时间我会尽快尝试上述答案,但它需要的代码比您的想法要多得多。
    • 好的。我决定实际测试一下。我已经用一个工作版本编辑了我的答案。
    • 谢谢!我会尽快尝试。 prettyCheckable 的作者也可以为其他人修改他的代码。
    【解决方案2】:

    这里没有错。 Pretty Checkable 库就是这样工作的。

    它找到输入 dom 隐藏它们并放置动态 a 和 label 标记而不是该输入。如果你想发现输入是否被检查,你需要检查动态添加标签的类(Class =“checked”)。不是原来的输入标签。

    您需要为 prettycheckable 编写一个绑定并观察 a 标签的类。然后根据该标签的类更改绑定的检查值。

    http://knockoutjs.com/documentation/custom-bindings.html

    【讨论】:

    • 我会试试这个,一旦它起作用,就会给你一个已回答的支票。但我认为你是对的,不敢相信我没有想到这一点,它在我的 toungek 的尖端,但我对 knockoutjs 还是很陌生。一旦我开始工作,我会在这里发布代码答案。
    • 你的方法也可以,但它需要更多的代码,我认为 pretty checkable 的创建者应该修改他的库以支持主要的 js 框架,因为它们现在被广泛使用并且人们想要使用他们使用这个插件和引导程序。
    【解决方案3】:

    @Michael 对 prettyCheckbox 的修改大部分 有效,但如果您的 viewModel 在加载时已经做出选择,prettyCheckbox 将无法识别它,因为它正在寻找“已选中”属性 而敲除/普通香草 html 将通过 属性 将复选框标记为选中。

    在 prettyCheckbox 中更改:

    var isChecked = el.attr('checked') !== undefined ? 'checked' : '';
    

    var isChecked = el.prop('checked') == true ? 'checked' : '';
    

    另外,重要的是要知道,如果您在代码中修改您的淘汰视图模型属性,它不会反映在 prettyCheckbox 中,因为我不知道订阅(在 javascript 中,而不是淘汰赛)更改一个财产。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-19
      • 1970-01-01
      • 2017-04-19
      • 1970-01-01
      • 2012-01-18
      相关资源
      最近更新 更多