2013-01-04 21 views
14

अपने मॉडल में एक एकीकृत सूची दिखाएँ मैं के समान डेटा है:AngularJS

$scope.list = [{id:0,tags:['tag1','tag2']},{id:2,tags:['tag2']}}; 

मैं टैग की एक सूची प्रदर्शित करना चाहते हैं चेक बॉक्स के साथ ('tag1' और 'tag2' की अनन्य मान शामिल हैं)। उम्मीद है कि जैसे कुछ:

<div ng-repeat="tag in list.tags"> 
    <label class="checkbox"> 
     <input type="checkbox" ng-model="filter.tag" /> 
     {{tag}} 
    </label> 
</div> 

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

उत्तर

26

आप तीन कार्रवाई करने के लिए देख रहे: एक ही सरणी में इन फ़्लैट $scope.list

  • में

    • प्रत्येक आइटम से टैग की सरणी जाओ
    • इस सरणी से अद्वितीय मान जाओ

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

    के इस कोड के साथ शुरू करते हैं:

    $scope.list = [ 
        {id: 0, tags: ['tag1', 'tag2']}, 
        {id: 1, tags: ['tag2']}, 
        {id: 2, tags: ['tag1', 'tag3', 'tag4']}, 
        {id: 3, tags: ['tag3', 'tag4']} 
    ]; 
    

    अब, चलो पहले कार्रवाई करने दें: $scope.list में प्रत्येक वस्तु के लिए tags संपत्ति से सरणी मिलता है। अंडरस्कोर pluck विधि प्रदान करता है, जो हमें वही चाहिए जो हमें चाहिए।

    प्लक_.pluck(list, propertyName)

    क्या शायद नक्शे के लिए सबसे आम उपयोग-मामला है का एक सुविधाजनक संस्करण: संपत्ति मूल्यों की एक सूची निकालने।

    प्लक का उपयोग करते हुए, हम निम्नलिखित प्राप्त कर सकते हैं:

    var tags = _.pluck($scope.list, 'tags'); 
    // gives us [['tag1', 'tag2'], ['tag2'], ['tag1', 'tag3', 'tag4'], ['tag3', 'tag4']] 
    

    अब, हम है कि सरणी समतल करना चाहते हैं।

    समतल_.flatten(array, [shallow])

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

    tags = _.flatten(tags); 
    // gives us ['tag1', 'tag2', 'tag2', 'tag1', 'tag3', 'tag4', 'tag3', 'tag4'] 
    

    अंत में, आप केवल एक टैग का एक उदाहरण चाहते हैं।

    uniq_.uniq(array, [isSorted], [iterator]) उपनाम: unique

    सरणी का डुप्लिकेट-नि: शुल्क संस्करण उत्पन्न करता है, === वस्तु समानता परीक्षण करने के लिए इस्तेमाल करते हैं। यदि आप पहले से जानते हैं कि सरणी सॉर्ट की गई है, तो IsSorted के लिए सत्य गुजरना एक बहुत तेज़ एल्गोरिदम चलाएगा।यदि आप एक परिवर्तन के आधार पर अद्वितीय वस्तुओं की गणना करना चाहते हैं, तो एक इटरेटर फ़ंक्शन पास करें।

    tags = _.unique(tags) 
    // gives us ['tag1', 'tag2', 'tag3', 'tag4'] 
    

    हम इन एक साथ श्रृंखला के लिए अंडरस्कोर के उपयोगी chain विधि के साथ इन एक साथ जोड़ सकते हैं। की गुंजाइश है कि अद्वितीय टैग रिटर्न पर एक समारोह बनाएँ:

    $scope.uniqueTags = function() { 
        return _.chain($scope.list) 
        .pluck('tags') 
        .flatten() 
        .unique() 
        .value(); 
    }; 
    

    चूंकि यह एक समारोह है, यह हमेशा अद्वितीय टैग, कोई फर्क नहीं पड़ता वापस आ जाएगी हम इस तथ्य के बाद $scope.list में आइटम जोड़ या निकाल देते हैं।

    अब आप uniqueTags पर ng-repeat का उपयोग प्रत्येक टैग को दिखाने के लिए कर सकते हैं: http://jsfiddle.net/BinaryMuse/cqTKG/

  • +0

    बिल्कुल सही! और साथ ही साथ एक महान स्पष्टीकरण भी! –

    +0

    धन्यवाद! मदद करने के लिए खुश है।^_^ –

    +0

    इस तरह के एकत्रीकरण समारोह का उपयोग करने के लिए प्रदर्शन क्या है? कोणीय कितनी बार समारोह कॉल करेगा? – oldwizard

    3

    का एक अद्वितीय सेट/सरणी प्राप्त करने के लिए एक कस्टम फ़िल्टर का उपयोग करें:

    <div ng-repeat="tag in uniqueTags()"> 
        <label class="checkbox"> 
        <input type="checkbox" ng-model="filter.tag" /> 
        {{tag}} 
        </label> 
    </div> 
    

    यहाँ एक काम कर jsFiddle कि इस तकनीक को दर्शाता है है टैग, एनजी-दोहराने के साथ उपयोग के लिए उपयुक्त:

    .filter('uniqueTags', function() { 
        return function(list) { 
         var tags = {}; 
         angular.forEach(list, function(obj, key) { 
          angular.forEach(obj.tags, function(value) { 
           tags[value] = 1; 
          }) 
         }); 
         var uniqueTags = [] 
         for (var key in tags) { 
          uniqueTags.push(key); 
         } 
         return uniqueTags; 
        } 
    }); 
    

    मैंने पहले टैग को किसी ऑब्जेक्ट में रखा, जो ऑटोमा तकनीकी रूप से हमें विशिष्टता देता है। फिर मैं इसे एक सरणी में बदल देता हूं। इस प्रकार

    उपयोग:

    <div ng-repeat="tag in list | uniqueTags"> 
    

    Fiddle

    <input type="checkbox" ng-model="filter.tag"> 
    

    यह $ गुंजाइश गुण filter.tag1 पैदा नहीं करता और filter.tag2 नियंत्रक गुंजाइश पर (यानी, गुंजाइश:


    निम्नलिखित मैं क्या लगता है कि आप शायद/यह करने की उम्मीद करना चाहते हैं नहीं कर सकते जहां एनजी-दोहराया जाता है)। एनजी-दोहराने का प्रत्येक पुनरावृत्ति अपने स्वयं के बच्चे के दायरे को बनाता है, इसलिए उपरोक्त एनजी-मॉडल प्रत्येक एनजी-दोहराने वाले बच्चे के दायरे पर स्कोप प्रॉपर्टी filter.tag बनाएगा, जैसा कि मेरी पहेली में दिखाया गया है।