2012-07-02 14 views
32

मुझे नॉकआउट "चेक" बाध्यकारी के साथ समस्या हो रही है। ऐसा लगता है कि चेकबॉक्स पर "चेंज" ईवेंट पुराने मूल्य को पुराना मान देता है, इसे अद्यतन करने से पहले (इसलिए यदि यह अनचेक किया गया तो यह झूठा होगा)। मुझे नहीं लगता कि मैं मूल्य की सदस्यता ले सकता हूं क्योंकि मेरे पास ऑब्जेक्ट के अंदर है।नॉकआउट चेकबॉक्स परिवर्तन घटना पुराने मान भेजती है

<tbody data-bind="foreach: Categories"> 
       <tr> 
        <td><input type="checkbox" data-bind="checked: ShowOpened, event: { change: $root.CategoryChange }" /></td> 
       </tr> 
      </tbody> 
<script type="text/javascript"> 
var Category = function (Id, Name, Order, ShowOpened) { 
    this.Id = Id; 
    this.Name = Name; 
    this.Order = Order; 
    this.ShowOpened = ShowOpened; 
    this.IsUpdated = ko.observable(false); 

    this.OldOrder = Order; 
    this.OldShowOpened = ShowOpened; 
}; 
var ViewModel = { 
    Categories: ko.observableArray([]), 
    CategoryChange: function(pCategory) { 
     if(pCategory.Order != pCategory.OldOrder || pCategory.ShowOpened != pCategory.OldShowOpened) 
      pCategory.IsUpdated(true); 
     else 
      pCategory.IsUpdated(false); 
    } 
}; 
ko.applyBindings(ViewModel); 
</script> 

तो इस उदाहरण में मैं चेकबॉक्स कि CategoryChange विधि है कि वस्तु के अंदर एक चर बदल जाएगा (है कि मैं बाद में की जरूरत है पता है कि वस्तु अपडेट किया जाता है) ट्रिगर कर सकते हैं ShowOpened है। लेकिन जब चेचबॉक्स बदल जाता है तो यह हमेशा पुराना मान भेजता है, ट्रिगरिंग विधि, और उसके बाद मान बदलता है। क्या इसको ठीक करने का कोई तरीका है?

+1

आपके कोड में कुछ गड़बड़ है। न तो 'दिखाया गया' और न ही 'IsUpdated' ko.observables हैं (और शायद यही कारण है कि आप हमेशा पुराने मान प्राप्त करते हैं)। यह कोड भी कैसे काम कर सकता है? 'श्रेणी बदलें 'को अपवाद फेंकना चाहिए। – freakish

+1

@freakish आप राइट कर रहे हैं, मैं एक गलती जब इस पोस्ट मूल रूप से बनाने की है। लेकिन फिर भी आपने जो त्रुटि दी है वह समस्या नहीं है। – akhabaiev

+0

ओई, अभी भी यह याद आ रही है: 'यह .ShowOpened = ko.observable (दिखाया गया); और यह:' pCategory.ShowOpened() '। मुझे कहना होगा, इस पोस्ट को लिखते समय आपने बहुत सी गलतियां की हैं ... – freakish

उत्तर

57

तरह दिखाई देंगे जब से तुम करते हुए कहा कि ko.observables की कमी कोई मुद्दा नहीं है पर कायम है, मैं इस पर करीब देखा है। ऐसा लगता है कि आप सही हैं! change ईवेंट को से से पहले वास्तविक मान सेट किया गया है। मुझे डर है कि मुझे इसका कारण पता नहीं है।

लेकिन वहाँ एक आसान तरीका यह तय करने के लिए है: बस click घटना के लिए change घटना बदलने के लिए:

<input type="checkbox" data-bind="checked: ShowOpened, click: $root.CategoryChange" /> 

याद रखें, स्पष्ट रूप से click ईवेंट हैंडलर के अंत में return true; डाल करने के लिए है कि आप। अन्यथा नया मान चेकबॉक्स पर सेट नहीं किया जाएगा।

यदि आप click ईवेंट का उपयोग नहीं करना चाहते हैं, तो आप इसे अन्य तरीके से कर सकते हैं। ShowOpened के परिवर्तनों की सदस्यता लें:

this.ShowOpened = ko.observable(ShowOpened); 
this.ShowOpened.subscribe(function(newValue) { 
    /* Do something when ShowOpened changes. 
     newValue variable holds the new value, obviously. :) */ 
}); 
+1

बढ़िया, ईवेंट काम पर क्लिक करें। मैंने इसे शुरू करने की कोशिश की, बस सच वापस लौटना भूल गया, और चेकबॉक्स कभी चेक/अनचेक नहीं हुआ। धन्यवाद। – akhabaiev

+0

आईई के साथ वास्तव में वही समस्या थी जो 'परिवर्तन' घटना को पहचान नहीं रही थी। Grr। – Brandon

+5

सही काम करता है! धन्यवाद। "वापसी सच;" ठीक से काम करने के लिए यह महत्वपूर्ण है! – mikemike396

6

ईवेंट बाध्यकारी के बजाय subscribe का उपयोग करने का प्रयास करें। यह काम करना चाहिए अब

<table> 
    <tbody data-bind="foreach: Categories"> 
     <tr> 
      <td><input type="checkbox" data-bind="checked: ShowOpened" /></td> 
     </tr> 
    </tbody> 
<table> 

var Category = function (Id, Name, Order, ShowOpened) { 
    this.Id = Id; 
    this.Name = Name; 
    this.Order = Order; 
    this.ShowOpened = ko.observable(ShowOpened); 
    this.IsUpdated = false; 

    this.OldOrder = Order; 
    this.OldShowOpened = ShowOpened; 

    this.ShowOpened.subscribe(function (newShowOpened) { 
     if(this.Order != this.OldOrder || this.ShowOpened() != this.OldShowOpened) 
      this.IsUpdated = true; 
     else 
      this.IsUpdated = false; 
    }, this); 
}; 
var ViewModel = { 
    Categories: ko.observableArray([]) 
}; 
ko.applyBindings(ViewModel); 

या विकल्प (और मेरी राय में एक बेहतर समाधान) के रूप में आप dependentObservable उपयोग कर सकते हैं, अब computed कहा जाता है। यहाँ यह तरह

<table> 
    <tbody data-bind="foreach: Categories"> 
     <tr> 
      <td> 
       <input type="checkbox" data-bind="checked: ShowOpened" /> 
       <span data-bind="text: IsUpdated"></span> 
      </td> 
     </tr> 
    </tbody> 
</table> 
var Category = function (Id, Name, Order, ShowOpened) { 
    this.Id = Id; 
    this.Name = Name; 
    this.Order = Order; 
    this.ShowOpened = ko.observable(ShowOpened); 
    this.OldOrder = Order; 
    this.OldShowOpened = ShowOpened; 
    this.IsUpdated = ko.computed(function() { 
     return this.Order != this.OldOrder || this.ShowOpened() != this.OldShowOpened; 
    }, this); 
}; 
var ViewModel = { 
    Categories: ko.observableArray([]) 
}; 
ko.applyBindings(ViewModel); 
0

मैं भी इस मुद्दे को नहीं था, लेकिन मैं क्योंकि मैं पहले से ही एक ajax अनुरोध है कि मान रीसेट कर सकता है के साथ एक ही क्षेत्र की सदस्यता ली गई थी समाधान सदस्यता लें का उपयोग नहीं कर सका। कोड बदलते समय कोड लूप में रहेगा। तो मैंने निम्नलिखित कार्यवाही (इसके बदसूरत लेकिन यह काम करता है) जोड़ा।

$("input[type='radio'], input[type='checkbox']", element).on("change", function (e, data) { 
    setTimeout(function() { 
     $(this).trigger("afterChange", data); 
    }.bind(this), 10); 
}); 

तो बजाय परिवर्तन सुनने पर मैं afterChange घटना को सुनना।

<div data-bind="foreach: answerList"> 
    <input type="checkbox" data-bind="event: { afterChange: $root.sendSelectedAnswer($data) }"/> 
</div> 

मुझे पता नहीं है कि यह सबसे अच्छा समाधान नहीं है, लेकिन मेरे मामले में मेरे पास कोई अन्य विकल्प नहीं था।

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