简体   繁体   English

与CSS绑定KnockoutJS复选框

[英]KnockoutJS checkbox binding with CSS

I have a Checkbox that its using KnockoutJS binding. 我有一个Checkbox,它使用KnockoutJS绑定。 The value is assigned to the input element but I can't see the checkbox being checked, only if I manually click on it. 该值将分配给输入元素,但只有在我手动单击它时才能看到要选中的复选框。

Behind the scenes the input element is working and getting the checked value to the property but becuase Im jQuery.uniforms.js to give a nice design to the forms then I guess that's why I'm not visually seeing the check on the checkbox. 在幕后输入元素工作并获取属性的检查值,但因为Im jQuery.uniforms.js为表单提供了一个很好的设计然后我想这就是为什么我没有在视觉上看到复选框上的检查。

<div class="inline">
   <input type="checkbox" data-bind='checked: permit.oneDayPermit' />
   <label>One Day Permit</label>
</div>

Im using jQuery.uniforms.js to give a nice design to the forms, so when inspecting the checkbox element I can see that a div and a span element are beign added to the code to make it look nicer: 我使用jQuery.uniforms.js为表单提供了一个很好的设计,所以在检查checkbox元素时,我可以看到divspan元素被添加到代码中以使其看起来更好:

<div class="checker">
  <span>
    <input type="checkbox" data-bind="checked: permit.oneDayPermit" value="[object Object]">
  </span>
</div>

When I click on the checkbox element to make it selected then the span element has a class named "checked": 当我单击复选框元素以使其选中时, span元素有一个名为“checked”的类:

<div class="checker">
  <span class="checked">
    <input type="checkbox" data-bind="checked: permit.oneDayPermit" value="[object Object]">
  </span>
</div>

Any clue on how can I solve this so the checkbox will get the check mark? 有关如何解决此问题的任何线索,以便复选框将获得复选标记?

Appreciate any help. 感谢任何帮助。

You can monkey-patch Knockout's built-in checked binding, like this: 你可以修补Knockout的内置checked绑定,如下所示:

ko.bindingHandlers.checked.update = (function () {
    var origialUpdate = ko.bindingHandlers.checked.update;
    return function (element, valueAccessor) {
        var parent = element.parentNode,
            checked = ko.unwrap(valueAccessor());

        origialUpdate.apply(this, arguments);

        if (parent.nodeName.toLowerCase() === "span") {
            ko.utils.toggleDomNodeCssClass(parent, "checked", checked);
        }
    };
})();

This snippet hijacks the update handler of the binding and toggles the checked class at the parent <span> element. 此代码段劫持绑定的update处理程序,并在父<span>元素处切换已checked类。 No jQuery code necessary, Knockout has all the required utility functions. 不需要jQuery代码,Knockout具有所有必需的实用程序功能。

You can implement a more elaborate version that does it with jQuery, though. 但是,您可以使用jQuery实现更精细的版本。

This way your binding code can stay the same. 这样你的绑定代码就可以保持不变。

http://jsfiddle.net/5TuTc/ http://jsfiddle.net/5TuTc/

Ok I'm pretty sure that you can use functions and methods in your bindings for KO. 好的,我很确定你可以在绑定中使用KO的函数和方法。 So for instance in checked you could add an anonymous function that sets the class of the parent above it. 因此,例如在check中你可以添加一个匿名函数来设置它上面的父类。 But rather you might want to bind your checked to a function in your ViewModel that can set the parent as well as the observable. 但您可能希望将已检查的绑定绑定到ViewModel中的一个函数,该函数可以设置父级和observable。

Lastly you could create a bindingHandler to nicely do this. 最后,你可以创建一个bindingHandler来很好地做到这一点。 The bindingHandler will be a custom action that will be applied initially and additionally upon any changes of the bound data. bindingHandler将是一个自定义操作,最初将应用于绑定数据的任何更改。 So when oneDayPermit experiences a change the update method will be fired. 因此,当oneDayPermit经历更改时,将触发update方法。 The bindingHandler will be sent a reference to the element (checkbox) as well as the binding, from here we can use jQuery to find its parent span and perform the addClass method on it. bindingHandler将被发送一个对元素(复选框)以及绑定的引用,从这里我们可以使用jQuery来查找它的父span并在其上执行addClass方法。

The KO Code: KO代码:

    ko.bindingHandlers.prettyCheck = {
        init: function (element, valueAccessor) {
            var value = valueAccessor();
            if (value()) {
                $(element).parent("span").addClass('checked');
            } else {
                $(element).parent("span").removeClass('checked');
            }
        },
        update: function (element, valueAccessor) {
            var value = valueAccessor();
            if (value()) {
                $(element).parent("span").addClass('checked');
            } else {
                $(element).parent("span").removeClass('checked');
            }
        }
    };

    function viewModel() {
        var self = this;
        self.oneDayPermit = ko.observable(false);
    }

    ko.applyBindings(new viewModel(), $("#checkerDiv")[0]);

Your HTML will look like this: 您的HTML将如下所示:

<div class="checker" id="checkerDiv">
  <span>
    <input type="checkbox" data-bind="prettyCheck: oneDayPermit, checked: oneDayPermit">
  </span>
</div>

Here's the fiddle: http://jsfiddle.net/jLqmc/21/ 这是小提琴: http//jsfiddle.net/jLqmc/21/

Alternately you could use a function instead of binding directly to an observable. 或者,您可以使用函数而不是直接绑定到observable。 Inside your function(which you could pass a reference of the element) you could toggle your observable and also perform jQuery operations on. 在函数内部(可以传递元素的引用),您可以切换observable并执行jQuery操作。 You will see 3 parameters here but the first one is I forget. 你会看到3个参数,但第一个是我忘了。 Its maybe something that is required by KO as a reference to the context and is not actually passed as a parameter. 它可能是KO作为上下文参考所需要的东西,实际上并不作为参数传递。 Anywho they two after are what is passed as parameters. 任何两个之后的任何东西都是作为参数传递的。

<div class="checker" id="checkerDiv">
  <span>
    <input type="checkbox" data-bind="checked: toggleCheck.bind($data, oneDayPermit, $(this))">
  </span>
</div>

In your VM 在您的VM中

self.toggleCheck= function (binding, element) {
  //Toggle Observable and do your Element stuffs
}

After loading data in Permit add following code: $('#checkerDiv .checkboxes').uniform(); 在Permit中加载数据后,添加以下代码:$('#checkerDiv .checkboxes')。uniform();

add class "checkboxes" or any other name to all the checkboxes that are binded. 将类“复选框”或任何其他名称添加到绑定的所有复选框。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM