2012-03-12 13 views
7

क्या कोई सरणी तत्वों को किसी सरणी के तत्वों में होने वाले परिवर्तनों के बारे में अधिसूचित किया गया है?एक सरणी के तत्वों के ko.computed ट्रैकिंग परिवर्तन

मेरी पहली सोचा क्योंकि

An observableArray tracks which objects are in the array, not the state of those objects

फिर भी, मैं कोड के इस टुकड़े पोस्टिंग कर रहा हूँ कि मैं क्या कोशिश कर रहा हूँ वर्णन करने के लिए observableArray उपयोग करने के लिए था, लेकिन यह काम नहीं किया, कर।

HTML:

<div data-bind="foreach:arr"> 
    <input type="text" value="" data-bind="value: a" /> 
</div> 

<div data-bind="foreach:arr"> 
    <p> 
     Field "a" is changed: <span data-bind="text: aChanged()? 'true': 'false'"></span> 
    </p> 
</div> 
<p> 
    Some "a" field from the array is changed: <span data-bind="text: someAChanged()? 'true': 'false'"></span> 
</p> 

जावास्क्रिप्ट:

function AppViewModel() { 
    this.arr = ko.observableArray([new A(), new A()]); 
    this.someAChanged = ko.computed(function() { 
     var ch = false; 
     var arr = this.arr(); 
     for (var i = 0; i < arr.length; i ++) { 
      if (arr[i].aChanged()) { 
       ch = true; 
       break; 
      } 
      return ch; 
     } 
    }, this);  
} 

function A() { 
    this.a = ko.observable(1); 
    this.aChanged = ko.computed(function() { 
     return this.a() != 1; 
    }, this); 
} 

ko.applyBindings(new AppViewModel()); 

मैं अपने खुद के सवालों के जवाब देने को कोई अधिकार नहीं है के रूप में, मैं अपने विचार यहाँ पोस्टिंग कर रहा हूँ। मैंने "सब्सक्राइब" फ़ंक्शन का उपयोग करने का निर्णय लिया। मेरा समाधान एक सरणी के तत्वों के लिए "पैरेंट" लिंक जोड़ना है। जब भी एक नमूदार क्षेत्र बदल जाती है एक माता पिता के क्षेत्र अपने बच्चों पर निर्भर भी बदल जाती है:

function Child() { 
    this._parent = null; 
    this.observableField = ko.observable(""); 
    this.observableField.subscribe(function (newVal) { 
     if (newVal... && this._parent) { 
      this._parent.anotherObservableField(...); 
     } 
    }); 
} 
Child.prototype._setParent(parent) {...} 

उत्तर

2

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

कुछ इस तरह काम करना चाहिए:

function AppViewModel() { 
    this.arr = ko.observableArray([new A(), new A()]); 
    this.someAChanged = ko.computed(function() { 
     var ch = false; 
     var changedItem = null; 
     var arr = this.arr(); 

     ko.utils.arrayForEach(this.arr(), function(item){ 
      var changed = item.changed(); //someAChanged registers a change subscription here 

      if(changed && !ch){ 
       ch = true; 
       changedItem = item; 
      } 
     }); 

     return changedItem; 
    }, this);  
}; 

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

उपरोक्त कोड भी बदले गए पहले आइटम को वापस कर देगा। मैंने माना कि यह वही है जो आप चाहते थे। यदि नहीं, तो बदली गई वस्तुओं की एक सरणी वापस करने के लिए इसे फिर से काम करना बहुत आसान होगा।

var initPrice = line.Price; 
    var initCurrency = line.IdCurrency; 

    self.isModified = ko.computed(function() { 
     return self.Price() !== initPrice || self.IdCurrency() !== initCurrency; 
    }); 
+0

[नवनीत गुप्ता] (http://stackoverflow.com/users/3846772/navneet-gupta) इस पोस्ट: "यह कैसे काम करता है, तो नए आइटम observableArray में जोड़ रहे हैं वे कैसे की सदस्यता ली है करते हैं? ? " –

+0

@ पीटरो कोई समस्या नहीं होनी चाहिए, क्योंकि गणना की गई 'this.arr() 'को आमंत्रित करती है, इसलिए यह सरणी के साथ-साथ' ko.utils.arrayForEach' कॉल 'में पंजीकृत होती है,' बदली 'प्रोप की सदस्यता लेगी नए जोड़े गए आइटम का। – Tyblitz

0

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

function AppViewModel() { 
    this.arr = ko.observableArray([new A(), new A()]); 
    this.someAChanged = ko.computed(function() { 
     var arr = this.arr(); 
     for (var i = 0; i < arr.length; i ++) { 
      if (arr[i]().aChanged()) { 
       return true; 
      } 
     } 
     return false; 
    }, this); 
} 
0

आप लगभग वहाँ थे मुझे लगता है कि:

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