नॉकआउट जेएस में रेडियो बटन के लिए सच / गलत बंधन


84

मेरे विचार मॉडल में मेरे पास एक IsMale मान है जिसका मूल्य सही या गलत है।

अपने UI में मैं इसे निम्न रेडियो बटन से बाँधना चाहता हूँ:

<label>Male
   <input type="radio" name="IsMale" value="true" data-bind="checked:IsMale"/>
</label> 
<label>Female
   <input type="radio" name="IsMale" value="false" data-bind="checked:IsMale"/>
</label>

मुझे लगता है कि समस्या checkedएक "सच" / "झूठी" स्ट्रिंग की उम्मीद है। तो मेरा सवाल यह है कि मैं इस तरह से यू / मॉडल और डब्ल्यू 2 बाइंडिंग कैसे प्राप्त कर सकता हूं?


10
नॉकआउट संस्करणों के लिए> = 3.0 देख नतन का जवाब एक सरल SOUTION से स्वीकार किए जाते हैं जवाब द्वारा सुझाए गए के लिए।
मार्कस Pscheidt

जवाबों:


81

एक विकल्प यह है कि एक लेखन योग्य गणना योग्य अवलोकन का उपयोग किया जाए ।

इस मामले में, मुझे लगता है कि एक अच्छा विकल्प है लेखन योग्य अभिकलन को अपने IsMaleअवलोकन योग्य "उप-अवलोकन योग्य" बनाना । आपका दृश्य मॉडल ऐसा दिखेगा:

var ViewModel = function() {
   this.IsMale = ko.observable(true);

   this.IsMale.ForEditing = ko.computed({
        read: function() {
            return this.IsMale().toString();  
        },
        write: function(newValue) {
             this.IsMale(newValue === "true");
        },
        owner: this        
    });          
};

आप इसे अपने UI में बांधेंगे जैसे:

<label>Male
   <input type="radio" name="IsMale" value="true" data-bind="checked:IsMale.ForEditing"/>
</label> 
<label>Female
   <input type="radio" name="IsMale" value="false" data-bind="checked:IsMale.ForEditing"/>
</label>

नमूना: http://jsfiddle.net/rniemeyer/Pjdse/


एक महान समाधान की तरह लगता है। मैं अपने VM को रीफ्रेश करने के लिए मैपिंग प्लगिन का उपयोग करता हूं। क्या आप जानते हैं कि यह IsMale पर ForEditing को मिटा देगा?
CJ

26
यहाँ एक विकल्प है जो गणना की गई अवलोकन योग्य रचना को एक कस्टम बाइंडिंग में धकेलता है, जो इसे बनाता है ताकि आपको मैपिंग प्लगइन में इससे निपटने के लिए परेशान न होना पड़े: jsfiddle.net/rniemeyer/utsvJ
RPememeyer

2
+1 प्रत्येक वस्तु पर एक देखने योग्य बनाने के बजाय एक बंधन का उपयोग करने के लिए
ग्रेग एननिस

1
@ RPNiemeyer निश्चित रूप से जाने का रास्ता है।
एंड्रयू

1
@ RPNiemeyer धन्यवाद! टिप्पणियों में वह बेला वह है जो मेरे लिए काम करती है।
SFlagg

128

मुझे पता है कि यह एक पुराना धागा है, लेकिन मुझे वही समस्या हो रही थी और एक बेहतर समाधान का पता चला जो संभवतः इस प्रश्न के आधिकारिक उत्तर के बाद नॉकआउट में जोड़ा गया था, इसलिए मैं इसे उसी समस्या वाले लोगों के लिए छोड़ दूँगा।

वर्तमान में एक्सटेंडर्स, कस्टम बाइंडिंग हैंडलर या कंप्यूटर्स की आवश्यकता नहीं है। बस एक "CheckValue" विकल्प प्रदान करें, यह html 'मान' विशेषता के बजाय इसका उपयोग करेगा, और इसके साथ ही आप किसी भी जावास्क्रिप्ट मान को पारित कर सकते हैं।

<input type="radio" name="a" data-bind="checked:IsChecked, checkedValue: true"/>
<input type="radio" name="a" data-bind="checked:IsChecked, checkedValue: false"/>

या:

<input type="radio" name="b" data-bind="checked:Quantity, checkedValue: 1"/>
<input type="radio" name="b" data-bind="checked:Quantity, checkedValue: 2"/>
<input type="radio" name="b" data-bind="checked:Quantity, checkedValue: 3"/>

2
स्रोत को देखते हुए, यहाँ पर चेक किए गए मूल्य का उपयोग करने का निर्णय लेना प्रतीत होता हैयदि इनपुट एक रेडियो या चेकबॉक्स है, तो एक सरणी के रूप में मान के साथ 'यूटीकैक्टवेड्यू' सही है । इसके अलावा, मैं नॉकआउट 3.0 का उपयोग कर रहा हूं। देखें कि क्या मदद मिलती है।
नाटन

1
हाँ, धन्यवाद, मैंने 3.0.0 में अपग्रेड किया है और अब यह वहां है। अभी भी मेरे बूलियन मानों को एक स्ट्रिंग में लपेटने की आवश्यकता है क्योंकि सर्वर कोड उन की उम्मीद कर रहा था ;-)
ZiglioUK

अच्छी जानकारी। दो अतिरिक्त बिंदु: (1) मैंने पाया कि पूर्व v3.0 नॉकआउट के साथ मैं valueबाध्यकारी और फिर checkedबाध्यकारी (उस क्रम में) का उपयोग करने में सक्षम था , लेकिन 3.0 के साथ मुझे checkedValueबाध्यकारी के बजाय बाध्यकारी का उपयोग करना पड़ा value। (2) प्री- v3.0 बाइंडिंग को सही ढंग से काम valueकरने के लिए बाइंडिंग की आवश्यकता के बारे में उपयुक्त था checked, इसलिए मुझे लगता है कि यदि आप checkedValueबाइंडिंग से पहले बाइंडिंग डालते हैं, तो सभी स्थितियों में v3.0 में चीजें बेहतर हो सकती हैं checked, जैसे वे डॉक्स में दिखाते हैं ।
जेसन फ्रैंक

@ZiglioNZ एक तरह से यह विफल हो सकता है यदि आपका checkedसेटर (या शायद इस पर निर्भर कुछ) त्रुटि उठाता है - तो सही चेकबॉक्स की जाँच नहीं की जाती है
शमौन_वेवर

मैं संस्करण 3.4 का उपयोग कर रहा हूं और पाता है कि मुझे अभी भी मूल्य = "सच" और इसके बाद के संस्करण को काम में लाना है।
१५:१६ पर १ble:

11

यह मेरे लिए काम करता है:

http://jsfiddle.net/zrBuL/291/

<label>Male
   <input type="radio" name="IsMale" value="1" data-bind="checked:IsMale"/>
</label> 
<label>Female
   <input type="radio" name="IsMale" value="0" data-bind="checked:IsMale"/>
</label>

एकमात्र समस्या जो मुझे दिखाई देती है वह यह है कि जब सर्वर पर जाने के लिए व्यूमोडेल को क्रमबद्ध किया जाता है, तो आपको देखने योग्य (बूलियनों के बजाय) में पूर्णांक मिलेंगे। आपको vm.IsMale(!!vm.+IsMale());सर्वर पर भेजने के लिए जसन को क्रमबद्ध करने से पहले कॉल करना होगा (यदि सर्वर साइड इसे ठीक से नहीं संभाल सकता है)
Artem

मुझे लगता है कि आप सही हैं, लेकिन मेरे जावास्क्रिप्ट ज्ञान की कमी है। क्या आप कृपया मुझे समझा सकते हैं कि कैसे !! + काम करता है? मैं w / उस वाक्यविन्यास से परिचित नहीं हूँ।
CJ

1
@CJ यह स्ट्रिंग या संख्या को बूलियन में परिवर्तित करता है - इस jsfiddle.net/nickolsky/6ydLZ को चबाएं , यदि स्ट्रिंग पहले से ही है तो यह इसे बूल के रूप में रखेगा
Artem

बहुत बहुत धन्यवाद। मुझे लगता है कि यह भी एक महान समाधान है।
CJ

1
हालांकि यह दोनों तरीकों से काम नहीं करता है। लोड होने पर रेडियो बटन की जाँच नहीं की जाती है।
मिकेल bergstberg

1
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);
        }
    }
};

बेवकूफ कोव परिकलित वेधशाला बनाने के बजाय इस बांधने की मशीन का उपयोग करें।

उदाहरण:

<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>

1

एक बार जब आप यह पता लगा लेते हैं कि रेडियो बटन के लिए प्रारंभिक मैच केवल एक स्ट्रिंग से मेल खाना चाहता है और एक स्ट्रिंग के लिए मूल्य सेट करना चाहता है, तो यह केवल आपके प्रारंभिक मूल्य को स्ट्रिंग में परिवर्तित करने का मामला है। मुझे Int मानों के साथ यह लड़ाई करनी थी।

जब आप अपने वेधशालाओं की स्थापना कर लेते हैं, तो मूल्य को स्ट्रिंग में बदल दें और KO वहां से अपना जादू चलाएगा। यदि आप अलग-अलग लाइनों के साथ मैप कर रहे हैं, तो उन लाइनों में रूपांतरण करें।

उदाहरण कोड में, मैं पूरे मॉडल को एक ही कमांड में मैप करने के लिए Json का उपयोग कर रहा हूं। फिर रेजर को रूपांतरण के लिए उद्धरणों के बीच मूल्य सम्मिलित करने देता है।

script type="text/javascript">
    KoSetup.ViewModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)));
    KoSetup.ViewModel.ManifestEntered("@Model.ManifestEntered");       //Bool
    KoSetup.ViewModel.OrderStatusID("@Model.OrderStatusID");           //Int
</script>

मैं विकास के दौरान अपने वेब पेज के निचले भाग में "स्क्रीन पर यह सब डंप करता हूं" का उपयोग करता हूं।

<h4>Debug</h4>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>

यहाँ डेटा मान हैं, इससे पहले

"OrderStatusID": 6,
"ManifestEntered": true,

और, के बाद

"OrderStatusID": "6",
"ManifestEntered": "True",

मेरी परियोजना में, मुझे बूल को बदलने की आवश्यकता नहीं थी, क्योंकि मैं एक चेकबॉक्स का उपयोग करने में सक्षम हूं जिसमें समान कुंठा नहीं है।


0

केवल 1 और 0 के बजाय सही और गलत क्यों नहीं?

 <label>Male
    <input type="radio" name="IsMale" value="true" data-bind="checked:IsMale"/>
 </label> 
 <label>Female
    <input type="radio" name="IsMale" value="false" data-bind="checked:IsMale"/>
 </label>

2
अगर आप json ऑब्जेक्ट भेज रहे हैं तो इससे फर्क पड़ता है।
डॉक्टर

0

आप एक एक्सटेंडर का उपयोग भी कर सकते हैं ताकि अधिक वेधशालाओं के लिए उनका पुन: उपयोग करना आसान हो:

ko.extenders.boolForEditing = function (target, allowNull) {
    var result = ko.computed({
        read: function () {
            var current = target();
            var newValue = null;
            if (current === undefined || current === null || current === '') {
                if (!allowNull) {
                    newValue = 'false';
                }
            } else {
                newValue = current ? 'true' : 'false';
            }
            return newValue;
        },
        write: function (newValue) {
            var current = target();
            var valueToWrite = null;
            if (newValue === undefined || newValue === null || newValue === '') {
                if (!allowNull) {
                    valueToWrite = false;
                }
            } else {
                valueToWrite = newValue === 'true';
            }
            // only write if it changed
            if (valueToWrite !== current) {
                target(valueToWrite);
            } else {
                if (newValue !== current) {
                    target.notifySubscribers(valueToWrite);
                }
            }
        }
    }).extend({
        notify: 'always'
    });

    result(target());

    return result;
};

फिर इसे इस तरह उपयोग करें:

this.IsMale.forEditing = this.IsMale.extend({boolForEditing: true});

यह boolForEditingइंगित करने के लिए प्रदान किया गया पैरामीटर कि क्या मान शून्य हो सकता है।

Http://jsfiddle.net/G8qs9/1/ देखें


0

3.0 से पहले नॉकआउट के पुराने संस्करण के लिए बहुत शोध करने के बाद संभवतः दो सबसे अच्छे विकल्प हैं

जैसे नॉकआउट एक्सटेंडर बनाएं

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;
};

अपने मॉडल पर एक्सटेंडर का उपयोग करने के लिए, आप निम्न की तरह कुछ करेंगे:

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>

स्रोत: http://www.timlabonne.com/2013/02/building-a-knockout-js-extender-for-boolean-values/

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.