2012-11-03 42 views
41

मुझे आश्चर्य है कि बाकिंग के दौरान नॉकआउटज को तर्क पारित करना संभव है या नहीं।नॉकआउटज ने गुजरने वाले पैरामीटर की गणना की

मैं चेकबॉक्स की एक सूची बाध्यकारी हूं और मेरे व्यूमोडेल में एक गणना की जाने वाली अवलोकन करने के लिए बाध्य करना चाहता हूं। मेरे व्यूमोडेल में (पढ़ने के फ़ंक्शन पर पारित पैरामीटर के आधार पर) मैं कुछ शर्तों के आधार पर सत्य/झूठी वापसी करना चाहता हूं।

var myViewModel=function(){ 
    this.myprop=ko.computed({read: function(){ 
    //would like to receive an argument here to do my logic and return based on argument. 
} 
}); 
}; 

<input type="checkbox" data-bind="checked: myprop(someval1)" /> 
<input type="checkbox" data-bind="checked: myprop(someval2)" /> 
<input type="checkbox" data-bind="checked: myprop(someval3)" /> 

कोई सुझाव?

उत्तर

81

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

फिर अपने बाध्यकारी में, उचित तर्क के साथ कार्य करें। इसकी गणना की गणना की गई गणना आपके दृश्य में बाध्य होगी और सामान्य रूप से अपडेट हो जाएगी।

यहां a fiddle है जहां मैंने ईवेंट हैंडलर बनाने के लिए इस तकनीक का उपयोग किया था। आप यहां कुछ ऐसा कर सकते हैं।

आप कार्य को देखने योग्य तरीके से एक विधि बनाकर इसे साफ रख सकते हैं। या तो ko.observable.fn प्रोटोटाइप को जोड़कर या इसे सीधे देखने योग्य उदाहरण में जोड़कर।

ko.observable.fn.bit = function (bit) { 
    return ko.computed({ 
     read: function() { 
      return !!(this() & bit); 
     }, 
     write: function (checked) { 
      if (checked) 
       this(this() | bit); 
      else 
       this(this() & ~bit); 
     } 
    }, this); 
}; 
// or 
function ViewModel() { 
    this.flags = ko.observable(0); 

    this.flags.bit = function (bit) { 
     return ko.computed({ 
      read: function() { 
       return !!(this() & bit); 
      }, 
      write: function (checked) { 
       if (checked) 
        this(this() | bit); 
       else 
        this(this() & ~bit); 
      } 
     }, this); 
    }.bind(this.flags); 
}  

तो अगर आप सिर्फ आपके विचार मॉडल में एक भी मूल्य के लिए उन सभी चेक बॉक्स बाध्य करने के लिए कोशिश कर रहे हैं आपके विचार

<input type="checkbox" data-bind="checked: flags.bit(0x1)"/> 
<input type="checkbox" data-bind="checked: flags.bit(0x2)"/> 
<input type="checkbox" data-bind="checked: flags.bit(0x4)"/> 
<input type="checkbox" data-bind="checked: flags.bit(0x8)"/> 

Demo


हालांकि करने के लिए लागू होते हैं, आप डॉन ' टी करने की जरूरत नहीं है। अपने दृश्य मॉडल में किसी सरणी पर checked बाइंडिंग का उपयोग करें और अपने चेकबॉक्स को एक मान दें। प्रत्येक चेक किए गए मान को सरणी में जोड़ा जाएगा। और यह दो तरह से बाध्यकारी होगा।

<input type="checkbox" data-bind="checked: checkedValues, value: 1"/> 
<input type="checkbox" data-bind="checked: checkedValues, value: 2"/> 
<input type="checkbox" data-bind="checked: checkedValues, value: 3"/> 
<input type="checkbox" data-bind="checked: checkedValues, value: 4"/> 
var viewModel = { 
    checkedValues: ko.observableArray([]) 
}; 

Demo

+1

धन्यवाद, यह बहुत अच्छा है। वास्तव में मैं जो खोज रहा था। –

0

बारीकियों को जानने के बिना, ऐसा लगता है कि तुम क्या करना चाहिए एक ko.observableArray या गणना सरणी मूल्य को परिभाषित करने

HTML है जैसे:

myprop: <input data-bind="value: myprop"> 
<div data-bind="foreach: selections"> 
    <label> 
    <span data-bind="text: value"></span> 
    <input type="checkbox" data-bind="checked: selected"/> 
    </label> 
</div> 

जे एस:

$(function() { 
    function Model() { 
     this.self = this 
     self.myprop = ko.observable(14) 
     self.bits = [1, 2, 4, 8, 16, 32, 64, 128] 
     self.selections = ko.computed(function() { 
      return self.bits.map(function(bit) { 
       console.log(myprop() & bit) 
       return { 
        value: bit, 
        selected: (myprop() & bit) == bit 
       } 
      }) 
     }) 
    } 

    ko.applyBindings(new Model()) 
}) 

और मॉडल स्थिति

+0

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

+0

मुझे थोड़ा आगे बताने की कोशिश करें। Myprop = 14 कहें और मुझे तीन चेकबॉक्स मिले हैं जिनके बिट मान 2,4,8 हैं। इस मामले में सभी तीन चेकबोस की आवश्यकता है जांचें। अगर मैं myprop = 2 बदलता हूं, तो इस मामले में केवल पहले चेकबॉक्स को जांचना होगा और दो की जरूरतों को अनचेक करने की आवश्यकता होगी। कस्टम बाइंडिंग हैंडलर के बारे में सोच रहा हूं लेकिन यह सुनिश्चित नहीं है कि इसे कैसे किया जाए। मुझे आशा है कि इससे समझाए जाने में मदद मिलेगी हाथ में काम –

+0

कृपया ऊपर दिए गए संपादित उदाहरण को देखें। जॉन का दृष्टिकोण भी काम करता है, लेकिन मार्कअप से पैरामीटर नहीं, मॉडल में तर्क और डेटा पसंद करते हैं। – 7zark7

2

परिभाषित करने के लिए मार्कअप से मूल्यों को पारित नहीं करना computed मान का उपयोग करने का कोई कारण नहीं है। बस अपने व्यू मॉडल में एक फ़ंक्शन को परिभाषित करें और checked को बाध्य करें।

नीचे एक बहुत ही सरल उदाहरण है।

-

एचटीएमएल

<input type="checkbox" data-bind="checked: isEven(1)" /> 
<input type="checkbox" data-bind="checked: isEven(2)" /> 
<input type="checkbox" data-bind="checked: isEven(3)" />​ 

जे एस

var MyViewModel=function(){ 
    this.isEven = function(num) { 
     return (num % 2) == 0; 
    }; 
}; 
ko.applyBindings(new MyViewModel()); 

-

कहा जा रहा है यह एक अच्छा विचार की कोशिश और तर्क के रूप में ज्यादा पुश करने के लिए है कि जितना संभव हो सके अपने व्यू मॉडल में। एक दृश्य मॉडल बनाने की सलाह दी जाएगी जो आपके चेकबॉक्स को किसी ऑब्जेक्ट के रूप में मॉडल करे, और उसके बाद यह तर्क कि चेकबॉक्स को चेक किया जाना चाहिए, अंदर encapsulated किया जा सकता है।

-

संपादित करें: दो तरह से बाध्यकारी मैं एक नमूदार प्रबंधन के लिए एक एक्सटेंडर लिखा है ऐसा करने के लिए आवश्यकता के आधार पर।

http://jsfiddle.net/jearles/j6zLW/5/

ko.extenders.bitwise = function(target, bitCount) { 
    target.bits = [];  
    target.checked = ko.observableArray(); 

    // Create bit array based on requested number of bits 
    for (i=bitCount-1; i>=0; i--) { 
     target.bits.push(''+Math.pow(2, i)); 
    }   

    // Define a function to create bits 
    function makeBits(newValue) { 
     var num = !isNaN(newValue) ? parseInt(newValue) : 0; 
     var arr = []; 
     for (i=0; i<target.bits.length; i++) { 
      var bitValue = parseInt(target.bits[i]); 
      if ((num & bitValue) == bitValue) arr.push(target.bits[i]); 
     } 
     target.checked(arr); 
    } 

    // Define a function to combine bits 
    function makeBitwise(newBits) { 
     var num = 0; 
     for (i=0; i<target.bits.length; i++) { 
     if (newBits.indexOf(target.bits[i]) > -1) num += parseInt(target.bits[i]); 
     } 
     target(num); 
    } 

    // Create initial bits 
    makeBits(target()); 

    // Make bits whenever the value changes 
    target.subscribe(makeBits); 

    // Make number whenever the bits change 
    target.checked.subscribe(makeBitwise); 

    // Return the original observable 
    return target; 
}; 

var MyViewModel=function(){ 
    var self = this; 
    this.number = ko.observable(2).extend({ bitwise: 8}); 

}; 
ko.applyBindings(new MyViewModel());​ 
+0

आपकी प्रतिक्रिया के लिए धन्यवाद लेकिन यह एक समय पर बाध्यकारी की तरह काम करता है, है ना? यदि मूल्य बदल गया है तो मैं दृश्य मॉडल से परिवर्तन को वापस चेकबॉक्स में कैसे दबा सकता हूं? साथ ही जब चेकबॉक्स की चेक की गई स्थिति बदलती है तो मैं अपना व्यूमोडेल कैसे अपडेट कर सकता हूं? –

+0

यह निर्भर करता है कि आपको क्या करना है। इस पहेली को देखें: http://jsfiddle.net/jearles/j6zLW/ –

+0

बेवकूफ के लिए धन्यवाद! यह मेरी जरूरत के करीब है। कोई विचार क्यों फ़ंक्शन है, जब आप UI में चेकबॉक्स को चेक/अनचेक करते हैं तो सेट नहीं किया जाता है? –

6

स्वीकार किए जाते हैं जवाब सभ्य है, लेकिन अगर आप एक समारोह प्रत्येक बॉक्स के लिए एक ko.computed उत्पन्न करता है, तो आप कई गुमनाम गणना observables के साथ अनावश्यक भूमि के ऊपर जोड़ रहे हैं, जो आपकी चेकबॉक्स सूचियों को 4-5 विकल्पों से अधिक होने पर तेज़ी से जोड़ता है।

यह थोड़ा सा परिदृश्य का एक सरल कार्यान्वयन है, लेकिन गणना की गई कार्य जो भी हो सकती है।

<input type="checkbox" data-bind="checked: checkedList, value: 1" /> 
<label>Value 1</label> 
<input type="checkbox" data-bind="checked: checkedList, value: 2" /> 
<label>Value 2</label> 
<input type="checkbox" data-bind="checked: checkedList, value: 4" /> 
<label>Value 4</label> 
<input type="checkbox" data-bind="checked: checkedList, value: 8" /> 
<label>Value 8</label> 

स्क्रिप्ट:

var vm = function() { 
    var vm = this; 

    this.checkedList = ko.observableArray(); 
    this.bitwiseValue = ko.computed({ 
     read: function() { 
      return vm.checkedList().reduce(function (prev, curr) { 
       return prev | curr; 
      }, 0); 
     }, 
     write: function (myVal) { 
      vm.checkedList.removeAll(); 
      var placeValue = 1; 

      while(myVal > 0) { 
       if((myVal % 2) == 1) { 
        alert(placeValue); 
        vm.checkedList.push(placeValue.toString()); 
       } 

       myVal = myVal >>> 1;      
       placeValue = placeValue * 2; 
      } 
     } 
    }, this); 
} 

ko.applyBindings(vm); 

उदाहरण यहाँ बेला: http://jsfiddle.net/i_vargas3/RYQgg/

+0

यह बहुत अच्छा काम करता है, धन्यवाद। हालांकि, अगर मैं एक मूल्य आवंटित करता हूं bitwise करने के लिए यह बक्से की जांच नहीं करता है जहां यह चाहिए।कोई सुझाव? – Grandizer

+0

उदाहरण में पहेली को होने के लिए आपको रिटर्न हिट करना पड़ा था। मैंने इनपुट – Isaac

+0

पर 'valueUpdate' प्रविष्टि को शामिल करने के लिए बाइंडिंग को संशोधित किया है, यह बहुत बढ़िया धन्यवाद है! यहां एक आखिरी सवाल है, vm.bitwiseValue (6) जोड़ने जैसा लगता है; आवेदन से पहले बाइंडिंग बल्ले से किसी भी बॉक्स को चेक नहीं करेगा। क्या इसे सेट करने का कोई तरीका है जैसे कि आपको डेटाबेस से मूल्य मिला है? – Grandizer

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^