AngularJS 속성 별 정렬


93

내가하려는 것은 속성별로 일부 데이터를 정렬하는 것입니다. 여기에 내가 강인한 일을해야하지만 그렇지 않은 예가 있습니다.

HTML 부분 :

<div ng-app='myApp'>
    <div ng-controller="controller">
    <ul>
        <li ng-repeat="(key, value) in testData | orderBy:'value.order'">
            {{value.order}}. {{key}} -> {{value.name}}
        </li>
    </ul>
    </div>
</div>

JS 부분 :

var myApp = angular.module('myApp', []);

myApp.controller('controller', ['$scope', function ($scope) {

    $scope.testData = {
        C: {name:"CData", order: 1},
        B: {name:"BData", order: 2},
        A: {name:"AData", order: 3},
    }

}]);

그 결과 :

  1. A-> AData
  2. B-> BData
  3. C-> CData

... IMHO는 다음과 같아야합니다.

  1. C-> CData
  2. B-> BData
  3. A-> AData

내가 뭔가를 놓쳤습니까 (여기 에 실험 할 준비가 된 JSFiddle 이 있습니다)?

답변:


148

AngularJS의 orderBy 필터는 객체없이 배열 만 지원합니다. 따라서 정렬을 수행하는 자체 작은 필터를 작성해야합니다.

또는 처리하는 데이터 형식을 변경하십시오 (영향을받은 경우). 객체를 포함하는 배열은 기본 orderBy 필터로 정렬 할 수 있습니다.

AngularJS에 대한 orderObjectBy 필터 는 다음과 같습니다 .

app.filter('orderObjectBy', function(){
 return function(input, attribute) {
    if (!angular.isObject(input)) return input;

    var array = [];
    for(var objectKey in input) {
        array.push(input[objectKey]);
    }

    array.sort(function(a, b){
        a = parseInt(a[attribute]);
        b = parseInt(b[attribute]);
        return a - b;
    });
    return array;
 }
});

보기에서의 사용법 :

<div class="item" ng-repeat="item in items | orderObjectBy:'position'">
    //...
</div>

이 예에서 객체는 위치 속성이 필요하지만 뷰의 정의에 따라 객체의 모든 속성 (정수 포함)을 유연하게 사용할 수 있습니다.

예제 JSON :

{
    "123": {"name": "Test B", "position": "2"},
    "456": {"name": "Test A", "position": "1"}
}

다음은 사용법을 보여주는 바이올린입니다. http://jsfiddle.net/4tkj8/1/


1
이것은 훌륭합니다. asc / desc 정렬 옵션을 추가했습니다 : app.filter ( 'orderObjectBy', function () {return function (input, attribute, direction) {if (! angular.isObject (input)) return input; var array = [] ; for (var objectKey in input) {array.push (input [objectKey]);} array.sort (function (a, b) {a = parseInt (a [attribute]); b = parseInt (b [attribute]) ; return direction == 'asc'? a-b : b-a;}); return array;}}); HTML : <tr ng-repeat = "val in list | orderObjectBy : 'prop': 'asc'">
Jazzy

@Armin 이것이 배열과 같은 객체라면 어떨까요? 즉{1:'Example 1', 2:'Example 2', 3:'Example 3', ...}
Eugene

8
좋은 대답이지만 우리는 이런 식으로 객체의 키를 잃었습니다. 그것을 유지하기 위해, 그냥 필터의 새로운 배열의 행을 만드는 추가는 예 for(var objectKey in input) { input[objectKey]['_key'] = objectKey; array.push(input[objectKey]); }우리가 사용할 수있는처럼을<div ng-repeat="value in object | orderObjectBy:'order'" ng-init="key = value['_key']">
니콜라스 Janel에게

7
Angular.js 현재 객체 배열에서 속성 별 정렬을 지원 한다는 점은 주목할 가치가 ... | orderBy: 'name'있습니다..
Wildhoney

2
@Wildhoney이 질문은 객체를 포함하는 배열이 아니라 키로 객체를 정렬하는 것에 관한 것입니다.
Armin

31

꽤 쉬워요 그냥 이렇게 해

$scope.props = [{order:"1"},{order:"5"},{order:"2"}]

ng-repeat="prop in props | orderBy:'order'"

33
이것은 연관 배열에 대해 작동하지 않습니다.
MFB 2014

7

parseInt ()는 정수 값에 대해서만 작동한다는 것을 잊지 마십시오. 문자열 값을 정렬하려면 다음을 교체해야합니다.

array.sort(function(a, b){
  a = parseInt(a[attribute]);
  b = parseInt(b[attribute]);
  return a - b;
});

이것으로 :

array.sort(function(a, b){
  var alc = a[attribute].toLowerCase(),
      blc = b[attribute].toLowerCase();
  return alc > blc ? 1 : alc < blc ? -1 : 0;
});

6

angular-JS ( https://github.com/angular/angular.js/blob/master/src/ng/filter/orderBy.js ) 코드에서 볼 수 있듯이 ng-repeat는 개체와 함께 작동하지 않습니다. 다음은 sortFunction을 사용한 해킹입니다.

http://jsfiddle.net/sunnycpp/qaK56/33/

<div ng-app='myApp'>
    <div ng-controller="controller">
    <ul>
        <li ng-repeat="test in testData | orderBy:sortMe()">
            Order = {{test.value.order}} -> Key={{test.key}} Name=:{{test.value.name}}
        </li>
    </ul>
    </div>
</div>

myApp.controller('controller', ['$scope', function ($scope) {

    var testData = {
        a:{name:"CData", order: 2},
        b:{name:"AData", order: 3},
        c:{name:"BData", order: 1}
    };
    $scope.testData = _.map(testData, function(vValue, vKey) {
        return { key:vKey, value:vValue };
    }) ;
    $scope.sortMe = function() {
        return function(object) {
            return object.value.order;
        }
    }
}]);

4

http://docs.angularjs.org/api/ng.filter:orderBy 에 따르면 orderBy는 배열을 정렬합니다. 귀하의 경우에는 객체를 전달하므로 고유 한 정렬 기능을 구현해야합니다.

또는 배열 전달-

$scope.testData = {
    C: {name:"CData", order: 1},
    B: {name:"BData", order: 2},
    A: {name:"AData", order: 3},
}

http://jsfiddle.net/qaK56/을 살펴보십시오.


나는 그것이 배열과 함께 작동한다는 것을 알고있다. 그래서 해결책은 나만의 정렬 기능을 작성하는 것이다.
PrimosK 2013 년

귀하의 jsfiddle! = 귀하의 코드가 게시되었습니다. 다음은 귀하의 예에 적합한 jsfiddle입니다. jsfiddle.net/qaK56/92
mrzmyr

3

문제를 해결하려면 JSON 구조를 실제로 개선해야합니다.

$scope.testData = [
   {name:"CData", order: 1},
   {name:"BData", order: 2},
   {name:"AData", order: 3},
]

그럼 당신은 할 수 있습니다

<li ng-repeat="test in testData | orderBy:order">...</li>

문제는 (키, 값) 변수가 orderBy 필터에서 사용할 수 없으며 어쨌든 키에 데이터를 저장해서는 안된다는 것입니다.


2
중포 기지에 그에게)
MFB

지금까지 내가 아는 한, 당신은 중포 기지의 데이터를 생성
여호수아 Wooward

Firebase에 배열을 저장하면 배열의 키로 UID가 사용됩니다. 데이터 구조를 제어 할 수없는 상황이 많이 있으므로 제안 사항이 약간 휩쓸 릴 수 있습니다.
MFB 2014

무엇의 배열을 저장합니까? 하나는 항상 데이터 구조를 제어합니다. 또한 OP는 Firebase에 대해 언급하지 않습니다.
Joshua Wooward 2014-04-29

2

여기 내가 한 일이 있으며 작동합니다.
방금 문자열 화 된 객체를 사용했습니다.

$scope.thread = [ 
  {
    mostRecent:{text:'hello world',timeStamp:12345678 } 
    allMessages:[]
  }
  {MoreThreads...}
  {etc....}
]

<div ng-repeat="message in thread | orderBy : '-mostRecent.timeStamp'" >

내가 텍스트로 정렬하고 싶다면

orderBy : 'mostRecent.text'

2

다음 구문을 지원할 수있는 업그레이드 된 버전의 필터를 추가하겠습니다.

ng-repeat="(id, item) in $ctrl.modelData | orderObjectBy:'itemProperty.someOrder':'asc'

app.filter('orderObjectBy', function(){

         function byString(o, s) {
            s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
            s = s.replace(/^\./, '');           // strip a leading dot
            var a = s.split('.');
            for (var i = 0, n = a.length; i < n; ++i) {
                var k = a[i];
                if (k in o) {
                    o = o[k];
                } else {
                    return;
                }
            }
            return o;
        }

        return function(input, attribute, direction) {
            if (!angular.isObject(input)) return input;

            var array = [];
            for(var objectKey in input) {
                if (input.hasOwnProperty(objectKey)) {
                    array.push(input[objectKey]);
                }
            }

            array.sort(function(a, b){
                a = parseInt(byString(a, attribute));
                b = parseInt(byString(b, attribute));
                return direction == 'asc' ? a - b : b - a;
            });
            return array;
        }
    })

에서 아르 민이 스레드에서 자신의 답변을 제이슨과 알니 타크 덕분에 이 스레드 .


1

Armin의 대답 + 객체 유형 및 비 각도 키에 대한 엄격한 검사 $resolve

app.filter('orderObjectBy', function(){
 return function(input, attribute) {
    if (!angular.isObject(input)) return input;

    var array = [];
    for(var objectKey in input) {
      if (typeof(input[objectKey])  === "object" && objectKey.charAt(0) !== "$")
        array.push(input[objectKey]);
    }

    array.sort(function(a, b){
        a = parseInt(a[attribute]);
        b = parseInt(b[attribute]);
        return a - b;
    });

    return array;
 }
})

1

다음은 객체 내 에서 키 또는 키를 기준 으로 객체 정렬 할 수 있도록 합니다 .

템플릿에서 다음과 같이 할 수 있습니다.

    <li ng-repeat="(k,i) in objectList | orderObjectsBy: 'someKey'">

또는:

    <li ng-repeat="(k,i) in objectList | orderObjectsBy: 'someObj.someKey'">

필터 :

app.filter('orderObjectsBy', function(){
 return function(input, attribute) {
    if (!angular.isObject(input)) return input;

    // Filter out angular objects.
    var array = [];
    for(var objectKey in input) {
      if (typeof(input[objectKey])  === "object" && objectKey.charAt(0) !== "$")
        array.push(input[objectKey]);
    }

    var attributeChain = attribute.split(".");

    array.sort(function(a, b){

      for (var i=0; i < attributeChain.length; i++) {
        a = (typeof(a) === "object") && a.hasOwnProperty( attributeChain[i]) ? a[attributeChain[i]] : 0;
        b = (typeof(b) === "object") && b.hasOwnProperty( attributeChain[i]) ? b[attributeChain[i]] : 0;
      }

      return parseInt(a) - parseInt(b);
    });

    return array;
 }
})

objectList의 (k, i) 키가 0과 1로 변환되는 것이 정상입니까?
Ken Vernaillen 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.