2014-10-29 1 views
6

필자는 정렬 할 값을 추출하는 데 필요한 함수 집합을 반복 반복합니다.angularjs orderBy 여러 함수가있는 경우 어떻게 뒤집을 수 있습니까?

내 NG 반복은 다음과 같습니다

나는에 문제가 있어요 무엇
ng-repeat="row in rows | orderBy: [sortFnOne, sortFnTwo, ...]" 

, 나는 sortFnOne 반전 될하고자한다. 이들은 간단한 속성을 사용하여 액세스 할 수없는 문자열을 추출합니다. 데이터를 변환하여 정렬하려는 값을 생성하기 때문입니다. 간단 있다면

나는 다만 것 알고

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

이러한 기능은 단지 난 그냥 수 논리 값을 반환한다면! 반환 값은 원하는 결과를 얻지 만 일부는 문자열을 반환하고 일부는 YYYY-MM-DD 형식의 날짜를 반환합니다.

+1

대신 사용자 정의 필터를 쓰는 것이 좋습니다. 두 번째 인수 인'reverse' 플래그가'orderBy'를 제공하는 것이 전체 배열에만 적용된다는 것은 유감입니다. – miqid

+0

필터에 관한 두 번째 @miqid. 이 링크를보고 싶을 수도 있습니다. 그것은 당신을 도울 수 있습니다. http://justinklemm.com/angularjs-filter-ordering-objects-ngrepeat/ –

+0

최소한의 예를 들어 광고를 게시하거나 도움을주는 것이 더 쉬울 것입니다. –

답변

0

나는이 한계를 직접 경험했다 ... orderBy 필터를 사용하여 함수에 의해 수행 된 순서를 뒤집을 방법이 없다.

내가 알 수있는 한, 기본 자바 스크립트 API에서 이러한 종류의 복합 순서 (방향이 'A'오름차순이어서 'B'내림차순)를 재현하는 쉬운 방법은 없습니다.

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; 
} 

위의 내용은 연결된 Plunk의 비교기에 사용되는 기능입니다. 마지막에는 필드의 정렬을 반대로하는 것은 결과에 -1을 곱하는 것만큼이나 간단합니다.

관련 문제