ng-repeat의 사용자 정의 정렬 기능


113

사용자가 선택한 옵션에 따라 특정 숫자를 표시하는 타일 세트가 있습니다. 이제 표시된 숫자로 정렬을 구현하고 싶습니다.

아래 코드는 어떻게 구현했는지 보여줍니다 (부모 카드 범위에서 값을 가져 오거나 설정하여). 이제 orderBy 함수가 문자열을 사용하기 때문에 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 ) :

기능 : 게터 기능. 이 함수의 결과는 <, =,> 연산자를 사용하여 정렬됩니다.

따라서 자신 만의 함수를 작성할 수 있습니다. 예를 들어, opt1과 opt2의 합계를 기준으로 카드를 비교하고 싶다면 (이것을 구성하고 있습니다. 요점은 임의의 함수를 가질 수 있다는 것입니다) 컨트롤러에서 작성합니다.

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

그런 다음 템플릿에서 :

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

다음은 작동하는 jsFiddle입니다.

주목할 가치가있는 또 다른 점은 AngularJS 필터orderBy 의 한 예일 뿐이 므로 매우 구체적인 순서 지정 동작이 필요한 경우 고유 한 필터를 작성할 수 있습니다 ( 대부분의 사용 사례에는 충분해야 함).orderBy


좋습니다.하지만 이에 대한 필터도 만들 수 있습니까?
hugo der hungrige 2013

예, 여전히 작동합니다. 여기에 업데이트 된 버전이 있습니다
jahller 2013-08-23

문서에 여러 매개 변수에 대한 설명이없는 이유는 무엇입니까 ?? BTW : 감사합니다. 작동합니다. :)
mayankcpdixit 2014

이 접근 방식으로 여러 기준을 처리 할 수있는 방법을 알고 있습니까? myValueFunction에서 여러 값을 반환하려면 어떻게해야합니까?
akcasoy

26

허용되는 솔루션은 배열에서만 작동하고 객체 또는 연관 배열에서는 작동하지 않습니다. 불행히도 Angular는 배열 열거의 JavaScript 구현에 의존하기 때문에 객체 속성의 순서를 일관되게 제어 할 수 없습니다. 일부 브라우저는 사전 식으로 객체 속성을 반복 할 수 있지만 보장 할 수는 없습니다.

예를 들어 다음과 같은 할당이 주어집니다.

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

그리고 지시문 <ul ng-repeat="(key, card) in cards | orderBy:myValueFunction">ng-repeat는 정렬 순서에 관계없이 "card2"이전에 "card1"을 반복 할 수 있습니다.

이 문제를 해결하기 위해 개체를 배열로 변환하는 사용자 지정 필터를 만든 다음 컬렉션을 반환하기 전에 사용자 지정 정렬 함수를 적용 할 수 있습니다.

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-22193332


1
안된다는 건 알지만 그래야만합니다-고마워요.
Elia Weiss

7

다음 링크는 Angular의 필터를 매우 잘 설명합니다. ng-repeat 내에서 사용자 지정 정렬 논리를 정의하는 방법을 보여줍니다. http://toddmotto.com/everything-about-custom-filters-in-angular-js

속성이있는 개체를 정렬하는 경우 다음은 내가 사용한 코드입니다. (이 정렬은 표준 JavaScript 정렬 방법이며 각도에만 국한되지 않음) 열 이름은 정렬이 수행 될 속성의 이름입니다.

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

0

orderBy 함수와 함께 방향을 포함하려면 :

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

어디

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

emmmmm, 단지 통과 내가 당신이 쓴 것을 관찰 생각 myOrderbyFunction()대신 작성하여야 myOrderbyFunction없이 ()그것은 당신이 사용자 지정 정렬 제공하기 위해 각 요소의 두 쌍에 대해 호출됩니다.
Victor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.