Binding true / false to radio buttons in Knockout JS

后端 未结 8 2208
悲哀的现实
悲哀的现实 2020-11-30 22:09

In my view model I have a IsMale value that has the value true or false.

In my UI I wish to bind it to the following radio buttons:

相关标签:
8条回答
  • 2020-11-30 22:41
    ko.bindingHandlers['radiobuttonyesno'] = {
        'init': function (element, valueAccessor, allBindingsAccessor) {
            var stateHandler = function (property, allBindingsAccessor, key, value, checkIfDifferent) {
                if (!property || !ko.isObservable(property)) {
                    var propWriters = allBindingsAccessor()['_ko_property_writers'];
                    if (propWriters && propWriters[key])
                        propWriters[key](value);
                } else if (ko.isWriteableObservable(property) && (!checkIfDifferent || property.peek() !== value)) {
                    property(value);
                }
            };
    
            var updateHandler = function () {
                var valueToWrite;
    
                if ((element.type == "radio") && (element.checked)) {
                    valueToWrite = element.value;
                } else {
                    return; // "radiobuttonyesno" binding only responds to selected radio buttons
                }
    
                valueToWrite = (valueToWrite === "True") ? true : false;
    
                var modelValue = valueAccessor(), unwrappedValue = ko.utils.unwrapObservable(modelValue); //can be true of false
    
                stateHandler(modelValue, allBindingsAccessor, 'checked', valueToWrite, true);
            };
            ko.utils.registerEventHandler(element, "click", updateHandler);
    
            // IE 6 won't allow radio buttons to be selected unless they have a name
            if ((element.type == "radio") && !element.name)
                ko.bindingHandlers['uniqueName']['init'](element, function () { return true });
        },
        'update': function (element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor());
    
            value = value ? "True" : "False";
    
            if (element.type == "radio") {
                element.checked = (element.value == value);
            }
        }
    };
    

    Use this binder instead of creating stupid ko computed observables.

    Example:

    <label>Male
            <input type="radio" name="IsMale" value="True" data-bind="radiobuttonyesno:IsMale"/>
         </label> 
         <label>Female
            <input type="radio" name="IsMale" value="False" data-bind="radiobuttonyesno:IsMale"/>
         </label>
    
    0 讨论(0)
  • 2020-11-30 22:42

    After doing lot of research for older version of knockout prior to 3.0 there are possibly two best options

    Create a knockout extender like

    ko.extenders["booleanValue"] = function (target) {
        target.formattedValue = ko.computed({
            read: function () {
                if (target() === true) return "True";
                else if (target() === false) return "False";
            },
            write: function (newValue) {
                if (newValue) {
                    if (newValue === "False") target(false);
                    else if (newValue === "True") target(true);
                }
            }
        });
    
        target.formattedValue(target());
        return target;
    };
    

    To use the extender on your model, you’d do something like the following:

    function Order() {
      this.wantsFries= ko.observable(false).extend({ booleanValue: null });
    }
    
    <span>Do you want fries with that?</span>
    <label>
      <input type="radio" name="question" value="True"
                 data-bind="value: wantsFries.formattedValue" /> Yes
    </label>
    <label>
      <input type="radio" name="question" value="False"
                 data-bind="value: wantsFries.formattedValue" /> No
    </label>
    

    source:http://www.timlabonne.com/2013/02/building-a-knockout-js-extender-for-boolean-values/

    0 讨论(0)
提交回复
热议问题