অ্যাঙ্গুলারজেএস সম্পত্তি অনুসারে বাছাই করা


93

আমি যা করার চেষ্টা করছি তা হল সম্পত্তি অনুসারে কিছু ডেটা বাছাই করা। এখানে উদাহরণস্বরূপ যে আমার চেষ্টা করা উচিত কাজ করা উচিত তবে তা হয় না।

এইচটিএমএল অংশ:

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

জেএস অংশ:

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. এ -> অ্যাডাটা
  2. বি -> বিটাটা
  3. সি -> সিডিটা

... যে আইএমএইচওর মতো হওয়া উচিত:

  1. সি -> সিডিটা
  2. বি -> বিটাটা
  3. এ -> অ্যাডাটা

আমি কি কিছু মিস করেছি (এখানে পরীক্ষার জন্য জেএসফিডেল প্রস্তুত )?

উত্তর:


148

AngularJS এর ​​অর্ডার দ্বারা ফিল্টার কেবল অ্যারে সমর্থন করে - কোনও বস্তু নেই। সুতরাং আপনাকে একটি নিজস্ব ছোট ফিল্টার লিখতে হবে যা আপনার জন্য বাছাই করে।

অথবা আপনি যে ডাটার সাথে হ্যান্ডেল করেন তার ফর্ম্যাটটি পরিবর্তন করুন (যদি আপনার এটিতে প্রভাব থাকে)। দেশী অর্ডার দ্বারা ফিল্টার দ্বারা অবজেক্টযুক্ত একটি অ্যারে বাছাইযোগ্য।

এখানে AngularJS এর ​​জন্য আমার অর্ডারঅবজেক্টবি ফিল্টারটি রয়েছে:

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/


4
এটা অসাধারণ. আমি asc / desc বাছাই করার বিকল্পটি যুক্ত করেছি: app.filter ('অর্ডারওজেক্টবাই', ফাংশন () {রিটার্ন ফাংশন (ইনপুট, বৈশিষ্ট্য, দিকনির্দেশ)) যদি (! কৌণিক.আইসজেক্ট (ইনপুট)) রিটার্ন ইনপুট; ভার অ্যারে = [] ; ইনপুট-এ (var অবজেক্টি ইনপুট) {অ্যারে.পশ (ইনপুট [অবজেক্টকি]); ray অ্যারে.সোর্ট (ফাংশন (ক, খ) {এ = পার্সেন্ট (এ [অ্যাট্রিবিউট]); বি = পার্সিয়ান্ট (বি [অ্যাট্রিবিউট]) ; ফেরার দিকনির্দেশ == 'এসসি'? এ - বি: বি - ক;}); রিটার্ন অ্যারে;}}); এইচটিএমএলে: <ট্র এনজি-রিপিট = "তালিকায় ভাল | অর্ডারজেক্টবাই: 'প্রোপ': 'এসসি'">
জাজি

@ আরমিন যদি এটি অ্যারের মতো বস্তু হয়? অর্থাত্{1:'Example 1', 2:'Example 2', 3:'Example 3', ...}
ইউজিন

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']">
নিকোলাস জ্যানেল

7
এটি এতই Angular.js টুকুনি করে সমর্থন এখন বস্তুর একটি অ্যারের মধ্যে একটি সম্পত্তি দ্বারা বাছাই: ... | orderBy: 'name'
ওয়াইল্ডহনি 8

4
@ উইল্ডহনি এই প্রশ্নটি কীগুলির সাথে অবজেক্টগুলি অর্ডার করার বিষয়ে রয়েছে, অবজেক্টযুক্ত অ্যারে নয়।
আর্মিন

31

এটি বেশ সহজ, কেবল এটির মতো করুন

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

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

33
এটি সাহসী অ্যারেগুলির জন্য কাজ করে না, যা প্রশ্নটি এটি।
এমএফবি

7

ভুলে যাবেন না যে পার্সিয়ান্ট () কেবল পূর্ণসংখ্যা মানের জন্য কাজ করে। স্ট্রিংয়ের মানগুলি বাছাই করতে আপনার এটিকে অদলবদল করতে হবে:

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

আপনি কৌণিক-জেএস কোডে দেখতে পারেন ( https://github.com/angular/angular.js/blob/master/src/ng/filter/orderBy.js ) এনজি-রিপিট অবজেক্টের সাথে কাজ করে না। এখানে সাজানো ফাংশন সহ একটি হ্যাক।

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 অনুসারে অর্ডারবাই একটি অ্যারে বাছাই করে। আপনার ক্ষেত্রে আপনি কোনও বিষয় পাস করছেন, সুতরাং আপনাকে নিজের বাছাইয়ের কাজটি প্রয়োগ করতে হবে।

বা একটি অ্যারে পাস -

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

http://jsfiddle.net/qaK56/ এ একবার দেখুন


আমি জানি যে এটি অ্যারেগুলির সাথে কাজ করে .. সুতরাং সমাধানটি আমার নিজের বাছাই করা ফাংশনটি লিখতে হবে?
প্রিমস্কে

আপনার jsfiddle! = আপনার কোড আপনি পোস্ট করেছেন। এখানে আপনার উদাহরণের জন্য এটি সঠিক jsfiddle: jsfiddle.net/qaK56/92
mrzmyr

3

আপনার সমস্যাটি সমাধানের জন্য আপনার জেএসএন কাঠামোর সত্যিকারের উন্নতি করা উচিত:

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

তাহলে আপনি করতে পারেন

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

আমার মনে হয় সমস্যাটি হ'ল (কী, মান) ভেরিয়েবলগুলি অর্ডারবাই ফিল্টারটিতে উপলব্ধ নয় এবং আপনার কীগুলিতে কোনওভাবেই ডেটা সংরক্ষণ করা উচিত নয়



যতদূর আমি জানি, আপনি
ফায়ারবেসে

আপনি যদি ফায়ারবেসে কোনও অ্যারে সঞ্চয় করেন তবে এটি অ্যারের জন্য কী হিসাবে একটি ইউআইডি ব্যবহার করে। অনেকগুলি পরিস্থিতি রয়েছে যেখানে কেউ ডেটা স্ট্রাকচারের উপরে নিয়ন্ত্রণ পায় না, তাই আপনার পরামর্শটি কিছুটা ঝলকানো হতে পারে।
এমএফবি

কি একটি অ্যারের সঞ্চয়? একজনের সর্বদা ডেটা কাঠামোর উপর নিয়ন্ত্রণ থাকে। এছাড়াও ওপি ফায়ারবেস সম্পর্কে কিছুই উল্লেখ করেছে।
জোশুয়া ওয়াউয়ার্ড

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

আর্মিনের উত্তর + অবজেক্টের ধরণ এবং অ-কৌণিক কীগুলির জন্য একটি কঠোর চেক $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;
 }
})

অবজেক্টলিস্টে (k, i) কীগুলি 0 এবং 1 এর মধ্যে রূপান্তরিত হয় এটাই কি স্বাভাবিক?
কেন ভার্নাইলেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.