如何在ng-repeat中对JSON数据进行排序?

时间:2022-11-25 16:33:15

I am getting a server response and binding these data to view using ng-repeat. Now I want to sort these data by priceList and name. I am able to sort name using orderBy, but not with priceList. I want to sort the products based on priceList. Sorting with name will change the order of list while sorting by priceList will effect only the order of products of each category. It will effect the order of displayed category. Please help me resolve this.
My code:

我将获得一个服务器响应并使用ng-repeat将这些数据绑定到视图。现在我想按价格表和名称对这些数据进行排序。我能用orderBy排序,但不能用priceList排序。我想按价目表把产品分类。按名称排序会改变列表的顺序,而按价格表排序只会影响每个品类的产品顺序。它将影响显示类别的顺序。请帮我解决这个问题。我的代码:

<div ng-controller="Ctrl">
    <pre>Sorting predicate = {{predicate}};</pre>
    <hr/>
    <table class="friend">
        <tr>
            <th><a href="" ng-click="predicate = 'name'; reverse=false">Name</a>
            </th>
            <th><a href="" ng-click="predicate = 'priceList'>price</a></th>
        </tr>

    </table>


<div ng-repeat="data in _JSON[0].categories | orderBy:predicate">
       <div ng-repeat="vals in data.itemTypeResults |orderBy:'partTerminologyName'" id="{{vals.partTerminologyName}}">
`<h4 style="background-color: gray">{{vals.partTerminologyName}} : Position :{{vals.position}}</h4>`<br>


<div ng-repeat="val in vals.products">
    <b> Quantity:{{val[0].perCarQty}}</b><br>
    <b> part:{{val[0].partNo}}</b><br>
    <b>sku:{{val[0].sku}}</b><br>
    <b> qtyInStock:{{val[0].qtyInStock}}</b><br>
    <b> priceList:{{val[0].priceList}}</b><br>
    <b>priceSave:{{val[0].priceSave}}</b><br>
    <b> qtyDC:{{val[0].qtyDC}}</b><br>
    <b> qtyNetwork:{{val[0].qtyNetwork}}</b><br>
    <b> priceCore:{{val[0].priceCore}}</b><br>
        </div>
</div>      
    </div>

JS:

JS:

$scope._JSON = [
        {"categories":
            [
                {"id":14061,"name":"Drive Belts",
                    "itemTypeResults":[
                        {"partTerminologyName":"Serp. Belt",
                            "position":"Main Drive",
                            "products":{
                                "5060635":[
                                    {"perCarQty":2,"partNo":"5060635",
                                    "sku":"20060904","qtyInStock":2,"qtyNetwork":4,
                                    "qtyDC":6,"priceList":19.15,"priceSave":3.29,
                                    "priceCore":10.0}
                                ],
                                "635K6":[
                                    {"perCarQty":9,"partNo":"635K6",
                                        "sku":"10062449","qtyInStock":2,"qtyNetwork":4,
                                        "qtyDC":6,"priceList":18.15,"priceSave":3.21,"priceCore":10.0}
                                ]
                            }
                        }
                    ]
                },
                {"id":2610,"name":"Drive Belt Tensioners, Idlers, Pulleys & Components",
                    "itemTypeResults":[
                        {"partTerminologyName":"Drive Belt Tensioner Assembly",
                        "position":"N/A",
                            "products":{
                                "950489A":[
                                    {"perCarQty":4,"partNo":"950489A",
                                        "sku":"10150833","qtyInStock":2,"qtyNetwork":4,
                                        "qtyDC":6,"priceList":18.15,"priceSave":3.21,"priceCore":10.0
                                    }
                                ]
                            }},
                        {"partTerminologyName":"Drive Belt Idler Pulley","position":"N/A",
                            "products":{
                                "89161":[
                                    {"perCarQty":1,"partNo":"89161",
                                    "sku":"99995959","qtyInStock":2,"qtyNetwork":4,
                                    "qtyDC":6,"priceList":17.15,"priceSave":3.21,"priceCore":10.0}
                                ],
                                "951373A":[
                                    {"perCarQty":2,"partNo":"951373A","pla":"LTN",
                                    "plaName":"Litens",
                                    "sku":"10150926","qtyInStock":2,"qtyNetwork":4,
                                        "qtyDC":6,"priceList":18.15,"priceSave":3.21,"priceCore":10.0}
                                ]
                            }
                        }
                    ]
                }
            ]
        }
    ];
    $scope.predicate = '';

Fiddle: Fiddle

小提琴:小提琴

4 个解决方案

#1


2  

You might need to define a very good sorter function, or sort your products before they are interpreted by ng-repeat. I've created sorter function using underscore.js (or lodash).

您可能需要定义一个非常好的排序器函数,或者在使用ng-repeat解释产品之前对其进行排序。我使用下划线创建了sorter函数。js(或lodash)。

You can checkout the demo (or the updated demo). Products are first sorted by category and then sorted by price in every category.

您可以签出演示(或更新的演示)。产品首先按类别排序,然后按每个类别的价格排序。

<!-- in html -->
<button ng-click="sortFn=sortByPrice">Sort By Price</button>
<button ng-click="sortFn=doNotSort">Do not Sort</button>
...
<div ng-repeat="val in sortFn(vals.products)">
  ...
// in js
$scope.sortByPrice = function(products) {
  return _.sortBy(products, function(product) {
    return product.length > 0 ? product[0].priceList : 0;
  });
};

$scope.doNotSort = function(products) {
  return products;
};

$scope.sortFn = $scope.doNotSort; // do not sort by default

BTW: You are directly calling val[0], which is very dangerous, if the product does not contain any elements, your code will break. My code won't ;-)

顺便说一句:您正在直接调用val[0],这是非常危险的,如果产品不包含任何元素,您的代码将会被破坏。我的代码不会;-)


Update 1

更新1

The author asks me for a more pure Angular way solution.

作者问我一个更纯粹的角度方法的解。

Here is my answer: I think my solution is exactly in Angular way. Usually you can implement a filter (similar to orderBy) which wraps my sortByPrice. Why I don't do that, because you have ng-click to switch your order filter. I'd rather put control logic into a controller, not as pieces into view. This will be harder to maintain, when your project keeps growing.

我的答案是:我认为我的解完全是角的。通常,您可以实现一个过滤器(类似于orderBy),它包装我的sortByPrice。为什么我不这么做,因为你有ng-click来切换你的订单过滤器。我宁愿把控制逻辑放到控制器中,而不是把它放到视图中。当您的项目持续增长时,这将更难维护。


Update 2

更新2

Okay, to make the +50 worthy, here is the filter version you want, (typed with my brain compiler) Please check in fiddle

好的,为了让+50更有价值,这是你想要的过滤版本,(用我的大脑编译器输入)请检查小提琴

#2


0  

You need to organize the products in other estructure. For example:

您需要组织其他estructure中的产品。例如:

 $.each($scope._JSON[0].categories , function( i , e) {

        $.each(e.itemTypeResults, function(sub_i,sub_e) { 
        $.each(sub_e.products, function(itemTypeResults_i,product) {
            console.log(product);
            var aProduct = new Object();
          aProduct.priceList = product[0].priceList;
          aProduct.name = e.name;
            $scope.products.push(aProduct);  
        });

      } )

    });

The code is not very friendly but what i do is putt all the products in one array so they can be ordered by the price. You have the products inside categories so that's why angular is ordering by the price in each category.

代码不是很友好,但我所做的是将所有产品放在一个数组中,这样它们就可以按价格排序。你有产品在类别内,这就是为什么角是按每个类别的价格排序。

Fiddle: http://jsfiddle.net/7rL8fof6/1/

小提琴:http://jsfiddle.net/7rL8fof6/1/

Hope it helps.

希望它可以帮助。

#3


0  

Your fiddle updated: http://jsfiddle.net/k5fkocby/2/

你的小提琴更新:http://jsfiddle.net/k5fkocby/2/

Basically: 1. Digested the complex json object into a flat list of objects:

基本上:1。将复杂的json对象简化为一个平面对象列表:

var productsToShow = [];
for (var i=0; i < json[0].categories.length; i++){
    var category = json[0].categories[i];
    for (var j=0; j<category.itemTypeResults.length;j++){
    var item = category.itemTypeResults[j];       
    var products = item.products;    
    for (var productIndex in products) {
        var productItems = products[productIndex];
      for (var k=0; k<productItems.length;k++){
            var productItem = productItems[k];       

          // Additions:
          productItem.categoryName = category.name;                 
          productItem.partTerminologyName = item.partTerminologyName;
          productItem.position = item.position;                 

          productsToShow.push(productItem);          
        }
    }    
    } 
}
  1. Show category title only when needed by:

    只在需要时显示类别标题:

    ng-repeat="product in (sortedProducts = (productsToShow | orderBy:predicate))"

    ng-repeat="product in (sortedProducts = (productsToShow | orderBy:predicate) "

and

ng-show="sortedProducts[$index - 1].partTerminologyName != product.partTerminologyName"

#4


0  

you can sort from your database and get final JSON data..

您可以从数据库中进行排序并获得最终的JSON数据。

db.categories.aggregate([{$group : {category : {your condition} },         price: {$sort : { price: 1 } },}}])

#1


2  

You might need to define a very good sorter function, or sort your products before they are interpreted by ng-repeat. I've created sorter function using underscore.js (or lodash).

您可能需要定义一个非常好的排序器函数,或者在使用ng-repeat解释产品之前对其进行排序。我使用下划线创建了sorter函数。js(或lodash)。

You can checkout the demo (or the updated demo). Products are first sorted by category and then sorted by price in every category.

您可以签出演示(或更新的演示)。产品首先按类别排序,然后按每个类别的价格排序。

<!-- in html -->
<button ng-click="sortFn=sortByPrice">Sort By Price</button>
<button ng-click="sortFn=doNotSort">Do not Sort</button>
...
<div ng-repeat="val in sortFn(vals.products)">
  ...
// in js
$scope.sortByPrice = function(products) {
  return _.sortBy(products, function(product) {
    return product.length > 0 ? product[0].priceList : 0;
  });
};

$scope.doNotSort = function(products) {
  return products;
};

$scope.sortFn = $scope.doNotSort; // do not sort by default

BTW: You are directly calling val[0], which is very dangerous, if the product does not contain any elements, your code will break. My code won't ;-)

顺便说一句:您正在直接调用val[0],这是非常危险的,如果产品不包含任何元素,您的代码将会被破坏。我的代码不会;-)


Update 1

更新1

The author asks me for a more pure Angular way solution.

作者问我一个更纯粹的角度方法的解。

Here is my answer: I think my solution is exactly in Angular way. Usually you can implement a filter (similar to orderBy) which wraps my sortByPrice. Why I don't do that, because you have ng-click to switch your order filter. I'd rather put control logic into a controller, not as pieces into view. This will be harder to maintain, when your project keeps growing.

我的答案是:我认为我的解完全是角的。通常,您可以实现一个过滤器(类似于orderBy),它包装我的sortByPrice。为什么我不这么做,因为你有ng-click来切换你的订单过滤器。我宁愿把控制逻辑放到控制器中,而不是把它放到视图中。当您的项目持续增长时,这将更难维护。


Update 2

更新2

Okay, to make the +50 worthy, here is the filter version you want, (typed with my brain compiler) Please check in fiddle

好的,为了让+50更有价值,这是你想要的过滤版本,(用我的大脑编译器输入)请检查小提琴

#2


0  

You need to organize the products in other estructure. For example:

您需要组织其他estructure中的产品。例如:

 $.each($scope._JSON[0].categories , function( i , e) {

        $.each(e.itemTypeResults, function(sub_i,sub_e) { 
        $.each(sub_e.products, function(itemTypeResults_i,product) {
            console.log(product);
            var aProduct = new Object();
          aProduct.priceList = product[0].priceList;
          aProduct.name = e.name;
            $scope.products.push(aProduct);  
        });

      } )

    });

The code is not very friendly but what i do is putt all the products in one array so they can be ordered by the price. You have the products inside categories so that's why angular is ordering by the price in each category.

代码不是很友好,但我所做的是将所有产品放在一个数组中,这样它们就可以按价格排序。你有产品在类别内,这就是为什么角是按每个类别的价格排序。

Fiddle: http://jsfiddle.net/7rL8fof6/1/

小提琴:http://jsfiddle.net/7rL8fof6/1/

Hope it helps.

希望它可以帮助。

#3


0  

Your fiddle updated: http://jsfiddle.net/k5fkocby/2/

你的小提琴更新:http://jsfiddle.net/k5fkocby/2/

Basically: 1. Digested the complex json object into a flat list of objects:

基本上:1。将复杂的json对象简化为一个平面对象列表:

var productsToShow = [];
for (var i=0; i < json[0].categories.length; i++){
    var category = json[0].categories[i];
    for (var j=0; j<category.itemTypeResults.length;j++){
    var item = category.itemTypeResults[j];       
    var products = item.products;    
    for (var productIndex in products) {
        var productItems = products[productIndex];
      for (var k=0; k<productItems.length;k++){
            var productItem = productItems[k];       

          // Additions:
          productItem.categoryName = category.name;                 
          productItem.partTerminologyName = item.partTerminologyName;
          productItem.position = item.position;                 

          productsToShow.push(productItem);          
        }
    }    
    } 
}
  1. Show category title only when needed by:

    只在需要时显示类别标题:

    ng-repeat="product in (sortedProducts = (productsToShow | orderBy:predicate))"

    ng-repeat="product in (sortedProducts = (productsToShow | orderBy:predicate) "

and

ng-show="sortedProducts[$index - 1].partTerminologyName != product.partTerminologyName"

#4


0  

you can sort from your database and get final JSON data..

您可以从数据库中进行排序并获得最终的JSON数据。

db.categories.aggregate([{$group : {category : {your condition} },         price: {$sort : { price: 1 } },}}])