2014-10-29 8 views
6

मेरे पास ऑब्जेक्ट्स के एक सेट पर एक ng-repeat पुनरावृत्ति है जिसके लिए कुछ फ़ंक्शंस को उन मानों को निकालने की आवश्यकता होती है जिन्हें मैं सॉर्ट करना चाहता हूं।angularjs ऑर्डर कई कार्यों के साथ, रिवर्स कैसे करें?

मेरे एनजी-दोहराने इस तरह दिखता है:

ng-repeat="row in rows | orderBy: [sortFnOne, sortFnTwo, ...]" 

क्या मैं साथ परेशानी हो रही हूँ, मैं sortFnOne स्थिति में कर दिया चाहते हैं है। ये तारों को निकालने जा रहे हैं कि मैं सरल विशेषताओं का उपयोग नहीं कर सकता क्योंकि यह इन मानों को उत्पन्न करने के लिए डेटा पर कुछ रूपांतरण कर रहा है जिसे मैं सॉर्ट करने का प्रयास कर रहा हूं।

मैं अगर यह सरल थे जानता हूँ कि मैं बस जाएगा:

ng-repeat="row in rows | orderBy: ['-id', 'name', '-status', ...]" 

इन कार्यों सिर्फ बूलियन्स मैं बस सकता है लौटने रहे थे! परिणाम प्राप्त करने के लिए वापसी मूल्य, लेकिन इनमें से कुछ स्ट्रिंग लौट रहे हैं, और कुछ वाई वाई वाई वाई-एमएम-डीडी प्रारूप में लौट रहे हैं।

+1

क्या आपने इसके बजाय एक कस्टम फ़िल्टर लिखने पर विचार किया है? आपके मामले में यह एक शर्म की बात है कि 'रिवर्स' ध्वज (यानी दूसरा तर्क) 'ऑर्डरबी' की पेशकश केवल पूरे सरणी पर लागू होती है। फिल्टर के संबंध में – miqid

+0

मैं दूसरा @miqid। आप इस लिंक पर एक नज़र रखना चाहते हैं। यह आपकी मदद कर सकता है। http://justinklemm.com/angularjs-filter-ordering-objects-ngrepeat/ –

+0

न्यूनतम उदाहरण के साथ एक प्लंकर या फीडल पोस्ट करें, तो –

उत्तर

0

मैं इस सीमा में खुद आया हूं ... orderBy फ़िल्टर के साथ किसी फ़ंक्शन द्वारा किए गए ऑर्डर को बदलने में कोई रास्ता नहीं है।

जहां तक ​​मैं कह सकता हूं, मूल जावास्क्रिप्ट एपीआई में दिशा के साथ इस तरह के यौगिक क्रम को पुन: पेश करने का कोई आसान तरीका नहीं है ('ए' आरोही द्वारा 'बी' अवरोही द्वारा क्रमबद्ध)।

Array.prototype.sort एक तुलना समारोह (विवरण के लिए MDN docs देखें) लेकिन कोई रास्ता नहीं के माध्यम से बुनियादी आदेश प्रदान करता है करने के लिए आसानी से एक समारोह तुलना लिखे बिना सॉर्ट क्रम (विपरीत) स्विच करें और इसे मिश्रित आदेश देने के लिए कोई समाधान प्रदान करता है। हमें कई ऑर्डरिंग की दिशा और प्राथमिकता निर्दिष्ट करने के लिए एक कॉम्पैक्ट नोटेशन चाहिए।

मैंने इस समस्या को हल करने में कुछ समय पहले इस सहायक को लिखा था।

var orderByAgeThenName = new OrderByBuilder().asc(getAge).asc(getName).build(); 
    var friendsByAgeThenName = orderByAgeThenName(friends); 

    var orderByNameThenAge = new OrderByBuilder().desc(getName).asc(getAge).build(); 
    var friendsByNameThenAge = orderByNameThenAge(friends); 

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

मैं इस एक कोणीय फिल्टर करने के लिए अनुकूलित किया जा सकता है लगता है ...

Runnable नमूना:

angular.module('orderByExample', []) 
 
.controller('ExampleController', ['$scope', function($scope) { 
 
    var friends = 
 
    [{name:'Jon', phone:'555-1212', age:10}, 
 
    {name:'Zach', phone:'555-2276', age:7},      
 
    {name:'Zach', phone:'555-9876', age:19}, 
 
    {name:'Zach', phone:'555-9276', age:13},   
 
    {name:'Mike', phone:'555-4321', age:21}, 
 
    {name:'Adam', phone:'555-5678', age:35}, 
 
    {name:'Julie', phone:'555-8765', age:29}]; 
 

 
    function getName(f){ 
 
    return f.name; 
 
    } 
 

 
    function getAge(f){ 
 
    return f.age; 
 
    } 
 
    
 
    var orderByName  = new OrderByBuilder().desc(getName).build(); 
 
    var orderByNameAndAge = new OrderByBuilder().desc(getName).asc(getAge).build(); 
 

 
    $scope.friendLists = [ 
 
    {label:'Not Ordered', friends: friends}, 
 
    {label:'Name DESC', friends: orderByName(friends)}, 
 
    {label:'Name DESC, Age ASC', friends: orderByNameAndAge(friends)} 
 
    ]; 
 
    
 
}]); 
 

 

 

 

 
function OrderByBuilder(orderings){ 
 
    var _orderings = []; 
 

 
    return { 
 
    asc: function(fn){ 
 
     addOrdering(true,fn); 
 
     return this; 
 
    }, 
 
    desc: function(fn){ 
 
     addOrdering(false,fn); 
 
     return this; 
 
    }, 
 
    build: build 
 
    }; 
 

 
    function addOrdering(asc,fn){ 
 
    _orderings.push({ 
 
     getterFn: fn, 
 
     asc: asc 
 
    }); 
 
    return this; 
 
    } 
 

 
    function build(){ 
 
    var compare = _orderings.reverse().reduce(function(nextComparer, ordering){ 
 
     return getComparerFn(ordering, nextComparer); 
 
    },null); 
 

 
    return function(xs){ 
 
     return xs.slice().sort(compare); 
 
    }; 
 
    } 
 

 
    // a comparerFn has the following signature: 
 
    // \t \t function(a: obj, b: obj): int 
 

 
    function getComparerFn(ordering, nextComparer){ 
 
    var next = nextComparer || function(a,b){ return 0; }; 
 
    var getVal = ordering.getterFn; 
 

 
    return function(a,b){ 
 
     var aVal = getVal(a); 
 
     var bVal = getVal(b); 
 
     if(aVal < bVal){ return ordering.asc ? -1 : 1; } 
 
     if(aVal > bVal){ return ordering.asc ? 1 : -1; } 
 
     return next(a,b); 
 
    }; 
 
    } 
 
}
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.6/angular.min.js"></script> 
 
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> 
 

 
<div ng-app="orderByExample"> 
 
    <div ng-controller="ExampleController"> 
 
    <div class="row"> 
 
     <div ng-repeat="friendList in friendLists" class="col-sm-4"> 
 
     <h4>{{friendList.label}}</h4> 
 
     
 
     <table class="table table-bordered table-condensed"> 
 
      <tr> 
 
      <th>Name</th> 
 
      <th>Phone Number</th> 
 
      <th>Age</th> 
 
      </tr> 
 
      <tr ng-repeat="friend in friendList.friends"> 
 
      <td>{{friend.name}}</td> 
 
      <td>{{friend.phone}}</td> 
 
      <td>{{friend.age}}</td> 
 
      </tr> 
 
     </table> 
 
     </div> 
 
    </div> 
 
    </div> 
 
</div>

0

कोणीय आप के लिए तीसरा तर्क के रूप में एक तुलनित्र समारोह प्रदान करने के लिए अनुमति देता है द्वारा आदेश। यह तुलनित्र फ़ंक्शन आपको अपना ऑर्डर निर्दिष्ट करने की शक्ति देता है।

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

$scope.compareData = function(left, right) { 
    function compareValues(valueLeft, valueRight) { 
    var valueReturn; 
    if (!isNaN(parseInt(valueLeft)) && !isNaN(parseInt(valueRight))) { 
     valueReturn = 
     ((valueLeft * 1) < (valueRight * 1) 
     ? -1 
     : ((valueLeft * 1) > (valueRight * 1) ? 1 : 0)); 
    } else { 
     valueReturn = valueLeft.toString().localeCompare(valueRight.toString()); 
    } 
    return valueReturn; 
    } 
    var dataReturn = 0; 
    if (typeof right === "undefined") { 
    dataReturn = 1; 
    } else if (typeof left === "undefined") { 
    dataReturn = -1; 
    } else { 
    var valuesLeft = left.value.split(","); 
    var valuesRight = right.value.split(","); 
    for (var i = 0; (i < valuesLeft.length) && (dataReturn === 0); ++i) { 
     dataReturn = compareValues(valuesLeft[i], valuesRight[i]); 
     dataReturn *= ($scope.sortReverse && (i > 0)) ? -1 : 1; 
    } 
    } 
    return dataReturn; 
} 

ऊपर लिंक खनखनाहट में तुलनित्र के लिए इस्तेमाल किया कार्य है। अंत में ध्यान दें कि एक फ़ील्ड पर सॉर्ट को उलटना उतना आसान है जितना -1 से परिणाम गुणा करना।

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