एनजी-दोहराने में कस्टम सॉर्ट फ़ंक्शन


113

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

नीचे दिए गए कोड से पता चलता है कि मैंने इसे कैसे लागू किया है (मूल कार्ड स्कोप में मान प्राप्त करके / सेट करके)। अब, क्योंकि ऑर्डरबाय फ़ंक्शन एक स्ट्रिंग लेता है, इसलिए मैंने कार्ड स्कोप में एक चर सेट करने की कोशिश की, जिसे curOptionValue कहा जाता है और इसके द्वारा सॉर्ट किया जाता है, लेकिन यह काम नहीं करता है।

तो सवाल यह है कि, मैं एक कस्टम सॉर्ट फ़ंक्शन कैसे बनाऊं?

<div ng-controller="aggViewport" >
<div class="btn-group" >
    <button ng-click="setOption(opt.name)" ng-repeat="opt in optList" class="btn active">{{opt.name}}</button>
</div>
<div id="container" iso-grid width="500px" height="500px">
    <div ng-repeat="card in cards" class="item {{card.class}}" ng-controller="aggCardController">
        <table width="100%">
            <tr>
                <td align="center">
                    <h4>{{card.name}}</h4>
                </td>
            </tr>
            <tr>
                <td align="center"><h2>{{getOption()}}</h2></td>
            </tr>
        </table>        
    </div>
</div>

और नियंत्रक:

module.controller('aggViewport',['$scope','$location',function($scope,$location) {
    $scope.cards = [
        {name: card1, values: {opt1: 9, opt2: 10}},
        {name: card1, values: {opt1: 9, opt2: 10}}
    ];

    $scope.option = "opt1";

    $scope.setOption = function(val){
        $scope.option = val;
    }

}]);

module.controller('aggCardController',['$scope',function($scope){
    $scope.getOption = function(){
        return $scope.card.values[$scope.option];
    }
}]);

जवाबों:


192

वास्तव में orderByफ़िल्टर एक पैरामीटर के रूप में न केवल एक स्ट्रिंग बल्कि एक फ़ंक्शन भी ले सकता है। से orderBy: प्रलेखन https://docs.angularjs.org/api/ng/filter/orderBy ):

फ़ंक्शन: गेट्टर फ़ंक्शन। इस फ़ंक्शन का परिणाम <, =,> ऑपरेटर का उपयोग करके सॉर्ट किया जाएगा।

तो, आप अपना खुद का फ़ंक्शन लिख सकते हैं। उदाहरण के लिए, यदि आप ऑप्ट 1 और ऑप्ट 2 के योग के आधार पर कार्ड की तुलना करना चाहते हैं (मैं इसे बना रहा हूं, तो मुद्दा यह है कि आपके पास कोई मनमाना कार्य हो सकता है) आप अपने नियंत्रक में लिखेंगे:

$scope.myValueFunction = function(card) {
   return card.values.opt1 + card.values.opt2;
};

और फिर, अपने टेम्पलेट में:

ng-repeat="card in cards | orderBy:myValueFunction"

यहाँ काम कर रहा jsFiddle है

ध्यान देने योग्य बात यह है कि AngularJS फ़िल्टरorderBy का सिर्फ एक उदाहरण है, इसलिए यदि आपको एक बहुत ही विशिष्ट आदेश व्यवहार की आवश्यकता है, तो आप अपना फ़िल्टर लिख सकते हैं (हालाँकि अधिकांश उपयोग मामलों के लिए पर्याप्त होना चाहिए)।orderBy


यह अच्छा है, लेकिन क्या इसके लिए एक फिल्टर भी बनाना संभव है?
ह्यूगो डेर हुनग्रीग

हां, यह अभी भी काम कर रहा है। यहाँ एक अपडेटेड वर्जन है
jahller

डॉक्स में मल्टीपल परम के बारे में कोई विवरण क्यों नहीं है ?? BTW: धन्यवाद, यह काम करता है। :)
१६

क्या आप जानते हैं कि मैं इस दृष्टिकोण के साथ कई मानदंडों को कैसे संभाल सकता हूं? मैं myValueFunction से कई मान कैसे लौटा सकता हूं?
akcasoy

26

स्वीकृत समाधान केवल सरणियों पर काम करता है, लेकिन वस्तुओं या साहचर्य सरणियों पर नहीं। दुर्भाग्य से, चूंकि एंगुलर ऐरे एन्यूमरेशन के जावास्क्रिप्ट कार्यान्वयन पर निर्भर करता है, ऑब्जेक्ट प्रॉपर्टीज के क्रम को लगातार नियंत्रित नहीं किया जा सकता है। कुछ ब्राउज़र ऑब्जेक्ट गुण के माध्यम से लेक्सोग्राफिक रूप से पुनरावृति कर सकते हैं, लेकिन इसकी गारंटी नहीं दी जा सकती है।

उदा। निम्नलिखित कार्य को देखते हुए:

$scope.cards = {
  "card2": {
    values: {
      opt1: 9,
      opt2: 12
    }
  },
  "card1": {
    values: {
      opt1: 9,
      opt2: 11
    }
  }
};

और निर्देश <ul ng-repeat="(key, card) in cards | orderBy:myValueFunction">, एनजी-रिपीट "कार्ड 1" से पहले "कार्ड 2" पर पुनरावृति कर सकता है, भले ही क्रमबद्ध हो।

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

myApp.filter('orderByValue', function () {
  // custom value function for sorting
  function myValueFunction(card) {
    return card.values.opt1 + card.values.opt2;
  }

  return function (obj) {
    var array = [];
    Object.keys(obj).forEach(function (key) {
      // inject key into each object so we can refer to it from the template
      obj[key].name = key;
      array.push(obj[key]);
    });
    // apply a custom sorting function
    array.sort(function (a, b) {
      return myValueFunction(b) - myValueFunction(a);
    });
    return array;
  };
});

हम कस्टम फ़िल्टर के साथ संयोजन में (कुंजी, मान) जोड़ियों पर पुनरावृत्ति नहीं कर सकते (क्योंकि सरणियों के लिए कुंजी संख्यात्मक अनुक्रमित हैं), इसलिए टेम्पलेट को इंजेक्ट किए गए प्रमुख नामों के संदर्भ में अद्यतन किया जाना चाहिए।

<ul ng-repeat="card in cards | orderByValue">
    <li>{{card.name}} {{value(card)}}</li>
</ul>

एक सहयोगी सरणी पर एक कस्टम फ़िल्टर का उपयोग करने वाली एक वर्किंग फ़िडेल है: http://jsfiddle.net/av1mLpqx/1/

संदर्भ: https://github.com/angular/angular.js/issues/1286#issuecomment-2219193332


1
मुझे पता है कि मुझे नहीं करना चाहिए, लेकिन मुझे बस इतना करना है - धन्यवाद।
एलिया वीस

7

निम्नलिखित लिंक एंगुलर में फिल्टर को बहुत अच्छी तरह से समझाता है। यह दिखाता है कि एनजी-रिपीट के भीतर कस्टम सॉर्ट लॉजिक को कैसे परिभाषित किया जा सकता है। http://toddmotto.com/everything-about-custom-filters-in-angular-js

गुणों के साथ ऑब्जेक्ट को सॉर्ट करने के लिए, यह वह कोड है जिसका मैंने उपयोग किया है: (ध्यान दें कि यह सॉर्ट मानक जावास्क्रिप्ट सॉर्ट विधि है और कोणीय के लिए विशिष्ट नहीं है) कॉलम का नाम उस संपत्ति का नाम है जिस पर सॉर्ट करना है।

self.myArray.sort(function(itemA, itemB) {
    if (self.sortOrder === "ASC") {
        return itemA[columnName] > itemB[columnName];
    } else {
        return itemA[columnName] < itemB[columnName];
    }
});

0

ऑर्डरबी फ़ंक्शन के साथ दिशा को शामिल करने के लिए:

ng-repeat="card in cards | orderBy:myOrderbyFunction():defaultSortDirection"

कहाँ पे

defaultSortDirection = 0; // 0 = Ascending, 1 = Descending

ईएमएमएमएम, केवल पासिंग थिंकिंग मैं मानता हूं कि आपने लिखा था कि myOrderbyFunction()इसके बजाय आप myOrderbyFunctionबिना लिखेंगे (), यह प्रत्येक दो जोड़ी तत्वों के लिए लागू होता है ताकि आप कस्टम सॉर्टिंग प्रदान कर सकें।
विक्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.