2013-07-10 10 views
9

में एनजी-दोहराने के लिए लिखे गए फ़िल्टर के लिए पुनरावृत्ति त्रुटि को पचाने के लिए मैं फिल्टर लिखने की कोशिश कर रहा हूं लेकिन यह काफी निराशाजनक रहा है।

यहाँ फ़िल्टर कर

https://groups.google.com/forum/#!topic/angular/IEIQok-YkpU https://groups.google.com/forum/#!topic/angular/gEv1-YV-Ojg

मैं इसे बाहर की कोशिश की कुछ सफलता के साथ संसाधनों मैं एक 'हिस्सा' लिखने के लिए पीछा कर रहा था की एक जोड़ी है। लेकिन पाया कि संस्करण

के बीच व्यवहार में अंतर है $$ हैशकी का उत्पादन करने के लिए वर्णित विधियां 1.1.5 संस्करण में काम नहीं करती हैं। पहले बेला, जबकि दूसरी यात्रा त्रुटि में पैदा करता है, ठीक है, भले ही कोड बिल्कुल वैसा ही है:

http://jsfiddle.net/nRGTX/38/ - 1.0.3 संस्करण

http://jsfiddle.net/nRGTX/39/ - 1.1.5 संस्करण

Error: 10 $digest() iterations reached. Aborting! 
Watchers fired in the last 5 iterations: [["fn: $watchCollectionWatch; newVal: 16; oldVal: 14"],["fn: $watchCollectionWatch; newVal: 18; oldVal: 16"],["fn: $watchCollectionWatch; newVal: 20; oldVal: 18"],["fn: $watchCollectionWatch; newVal: 22; oldVal: 20"],["fn: $watchCollectionWatch; newVal: 24; oldVal: 22"]] 

क्या यह लिखने के लिए कोई कामकाज/उचित तरीका है?

उत्तर

12

संस्करण 1.1.4 से शुरू हो रहा है ng-repeat निर्देश उस संग्रह पर एक घड़ी है जिसे आप यह सुनिश्चित करने के लिए कर रहे हैं कि यह बदले नहीं है। जिस तरह से यह काम करता है वह यह है कि यह सरणी में प्रत्येक आइटम की तुलना करता है और यदि आइटम बराबर नहीं हैं (=== समझ में), तो ऐसा लगता है कि संग्रह अद्यतन किया गया है। कम से कम यह कोड को देखने से मेरी समझ है।

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

एकमात्र समाधान जो मैं साथ आया था, पहले लौटाए गए परिणामों का कैश बनाना था। हर बार जब खंड फ़िल्टर कहा जाता है, तो यह देखने के लिए जांच करता है कि आपने पहले एक ही सरणी और चंकसाइज के साथ एक फ़िल्टर किया है या नहीं। यदि ऐसा है, तो यह कैश्ड परिणाम देता है।

ऐसा करने के लिए, आप कुछ इस तरह देखने के लिए अपने फिल्टर समारोह अद्यतन करना चाहिए:

return function(array, chunkSize) { 
    if (!(array instanceof Array)) return array; 
    if (!chunkSize) return array; 

    // Create empty cache if it doesn't already exist. 
    if (typeof myApp.chunkCache === "undefined") { 
    myApp.chunkCache = []; 
    } 

    // Search the cache to see if we filtered the given array before. 
    for (var i = 0; i < myApp.chunkCache.length; i++) { 
    var cache = myApp.chunkCache[i]; 
    if (cache.array == array && cache.chunkSize == chunkSize) { 
     return cache.result; 
    } 
    } 

    // If not, construct the chunked result. 
    var result = chunkArray(array, chunkSize); 
    defineHashKeys(result); 

    // And then add that result to the cache. 
    var cache = { 
    array: array, 
    chunkSize: chunkSize, 
    result: result 
    }; 
    myApp.chunkCache.push(cache); 

    return result; 
} 

मैं यह भी कहना चाहिए कि आप शायद, defineHashKeys कॉल निकाल सकते हैं क्योंकि मैं इसे किसी भी कार्य करता है नहीं लगता है इस कोड में उद्देश्य। मैंने इसे केवल इसलिए छोड़ा क्योंकि यह आपके मूल कोड में था। जब मैंने इसे हटा दिया तो ऐसा कोई फर्क नहीं पड़ता।

+0

धन्यवाद जेम्स! कैश के साथ ... पृष्ठ पर एकाधिक खंड फ़िल्टर होने पर क्या होता है? मैंने यहां थोड़ा परीक्षण किया है http://jsfiddle.net/nRGTX/42/ और ऐसा लगता है कि यह 2 खंड फिल्टर के लिए काम करता है लेकिन मुझे आश्चर्य है कि ऐसा क्यों है क्योंकि मैं उम्मीद करता था कि फिल्टर एक-दूसरे को – zcaudate

+0

I कई फिल्टर के साथ परीक्षण किया - समाधान इस तरह काम करने के लिए डिजाइन किया गया था। ध्यान दें कि कैश सरणी और चंकसाइज के प्रत्येक संयोजन के लिए एक अलग प्रविष्टि संग्रहीत करता है, इसलिए विभिन्न आकारों या विभिन्न सरणी वाले दो फ़िल्टरों को संघर्ष नहीं करना चाहिए। –