【问题标题】:AngularJS orderBy Function With No SortingAngularJS orderBy 函数没有排序
【发布时间】:2014-01-30 19:30:55
【问题描述】:

我正在尝试使用自定义 orderBy 函数。最初,我希望数据按照添加到$scope.rows 的顺序显示,并且只有在单击列标题后才应按特定属性排序。这是我的小提琴:

http://jsfiddle.net/S8M4c/

这是我的观点:

<table ng-app ng-controller="ctrl">
    <tr>
        <th><a ng-click="orderBy = 'id'">ID</a></th>
        <th><a ng-click="orderBy = 'name'">Name</a></th>
    </tr>
    <tr ng-repeat="row in rows | orderBy:mySort">
        <td>{{row.object.id}}</td>
        <td>{{row.object.name}}</td>
    </tr>
</table>

这是我的控制器:

function ctrl($scope)
{
    // Initially, we don't sort by anything
    $scope.orderBy = "";
    $scope.rows = [];

    // Add some rows
    for(var i = 10;i < 30;i++)
    {
        $scope.rows.push({settings: {foo: true}, object: {id: i, name: "Name " + i}})   
    };

    $scope.mySort = function(row)
    {
        if($scope.orderBy != "")
        {
            return row.object[$scope.orderBy];
        }

        // What do I return here??
        return "";
    }
}

如果$scope.orderBy 没有设置,我想按原来的顺序返回$scope.rows,我在$scope.mySort 中返回什么?我不能return row.object.id,因为不能保证按 ID 顺序添加行。在 Chrome 32 上按原样运行我的代码,出现的第一行的 ID 为 20,即中间行。

【问题讨论】:

  • 只是猜测:return row.object.id ?
  • 问题是,在我的真实应用程序中,不能保证按 ID 的顺序添加行。事实上,它们可能(看起来)在第一次加载时完全未排序,这是期望的。我更新了我的问题以反映这一点。
  • 那么您最好的选择可能是为每个对象添加一个新属性 - 该属性应该表示可用于此排序的不断增长的索引。
  • 不幸的是,我无法向我的对象添加属性,因为它已绑定到 socketIO 和 Redis。对象本身不知道它在一个行对象中这一事实。这就是为什么我希望在使用自定义 orderBy 函数时有一种方法可以保持行的自然顺序。

标签: javascript angularjs angularjs-ng-repeat angularjs-orderby


【解决方案1】:

return $scope.rows.indexOf(row);

(Fiddle.)

您也可以使用开箱即用的orderBy 执行此操作,方法是提供一个将其作为默认谓词返回的函数:

控制器:

$scope.mySort = $scope.unsorted = function(row)
    {
        return $scope.rows.indexOf(row);
    }

查看:

<div ng-app ng-controller="ctrl">
    <table>
        <tr>
            <th><a ng-click="mySort = 'object.id'">ID</a></th>
            <th><a ng-click="mySort = 'object.name'">Name</a></th>
        </tr>
        <tr ng-repeat="row in rows | orderBy:mySort">
            <td>{{row.object.id}}</td>
            <td>{{row.object.name}}</td>
        </tr>
    </table>
    <button ng-click="mySort = unsorted;">Original Sort</button>
</div>

Fiddle here.(我更改了对象中使用的数字,以便按 id 排序、按名称排序和原始排序不完全相同。)

【讨论】:

    【解决方案2】:

    我认为你必须编写自己的sortby 函数。原始 angulars orderBy 是一个常规过滤器,它返回排序后的数组。您的过滤器可能如下所示:

    .filter('mySort', function(){
        return function(values, param){
            if(param===''){
                return values;
            }else{
                 // very important! create a copy of the array - otherwise 
                 // the $wtachCollection function will fire to often!
                 var arrayCopy = [];
                 for ( var i = 0; i < values.length; i++) { arrayCopy.push(values[i]); }
    
                return arrayCopy.sort(function(a,b){
                    var v1 = a.object[param];
                    var v2 = b.object[param];
                    // you know best how to sort it!
                    if (v1 === v2) return 0;
                    return v1 < v2 ? -1 : 1;
                });   
            }
        }
    })
    

    你可以这样使用这个过滤器:

    <table ng-app="myApp" ng-controller="ctrl">
        <tr>
            <th><a ng-click="orderBy = 'id'">ID</a></th>
            <th><a ng-click="orderBy = 'name'">Name</a></th>
        </tr>
        <tr ng-repeat="row in rows | mySort:orderBy">
            <td>{{row.object.id}}</td>
            <td>{{row.object.name}}</td>
        </tr>
    </table>
    

    这是您修改后的小提琴:http://jsfiddle.net/spRf6/ 我已经稍微更改了名称,因此您可能会看到排序有效。

    【讨论】:

      【解决方案3】:

      创建对象数组的副本,然后排序变得微不足道:

      控制器:

      $scope.objects = [];
      
      angular.forEach($scope.rows, function(row){
          $scope.objects.push(row.object);
      });
      

      查看:

      <tr ng-repeat="object in objects | orderBy:orderBy">
          <td>{{object.id}}</td>
          <td>{{object.name}}</td>
      </tr>
      

      不需要 mySort 函数。

      【讨论】:

      • 老实说,这可能是大多数情况下的答案。但是,在我的特定情况下,我需要将对象保留为行的属性,因为它在其他地方需要。不过谢谢!
      • 它仍然是。对象数组只包含对原始对象的引用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-14
      • 1970-01-01
      • 2015-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多