嵌套属性的角度顺序可能会丢失?

时间:2016-06-13 09:13:36

标签: javascript angularjs sorting

我有一个包含项目的列表,正如您在following plunkr中看到的那样,我尝试使用标准orderBy过滤器对表格进行排序:

<tr ng-repeat="item in list | orderBy: sorting.field : sorting.reverse">
     <!-- some code goes here -->
</tr>

请参阅下面的plunker或摘要:

&#13;
&#13;
var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {

  $scope.list = [{
    id: 1,
    title: 'test 1',
    reactions: {
      'like': 7,
      'share': 20,
      'comment': 100
    }
  }, {
    id: 2,
    title: 'test 2',
    reactions: {
      'like': 5,
      'share': 10,
    }
  }, {
    id: 3,
    title: 'test 3',
    reactions: {
      'like': 4,
      'share': 1,
    }
  }, {
    id: 4,
    title: 'test 4',
    reactions: {
      'like': 4,
      'share': 1,
      'comment': 2
    }
  }];

  $scope.sorting = {
    field: 'id',
    reverse: false
  };


});
&#13;
<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.5/angular.js" data-semver="1.3.5"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <div>
    <table>
      <tr>
        <th ng-click="sorting.field = 'id'; sorting.reverse = ! sorting.reverse;">ID</th>
        <th ng-click="sorting.field= 'title'; sorting.reverse = ! sorting.reverse;">Title</th>
        <th ng-click="sorting.field = 'reactions.like'; sorting.reverse = ! sorting.reverse;">Likes</th>
        <th ng-click="sorting.field = 'reactions.share'; sorting.reverse = ! sorting.reverse;">Shares</th>
        <th ng-click="sorting.field = 'reactions.comment'; sorting.reverse = ! sorting.reverse;">Comments</th>
      </tr>
      <tr ng-repeat="item in list | orderBy: sorting.field : sorting.reverse">
        <td>
          {{item.id}}
        </td>
        <td>
          {{item.title}}
        </td>
        <td>
          {{item.reactions.like}}
        </td>
        <td>
          {{item.reactions.share}}
        </td>
        <td>
          {{item.reactions.comment}}
        </td>
      </tr>
    </table>
    <div class="hint">
      <p>* Click on table heading in order to sort results.</p>
    </div>
  </div>
</body>

</html>
&#13;
&#13;
&#13;

当缺少某些属性时出现问题( n.b。 - 无法处理此问题,因为数据来自外部API ),请查看&#34;评论&#34;专栏,你会看到我在说什么。数据未按预期排序。

是的,我尝试了this线程中的所有内容,但似乎没有任何对我有用。

3 个答案:

答案 0 :(得分:1)

您可以在显示数据之前修复数据,而不是通过排序进行黑客攻击(您可以应用any sort function you want)。

var possibleReactions = ['like', 'share', 'comment'];
for (var i = 0; i < $scope.list.length; i++) {
  var item = $scope.list[i];
  for (var j = 0; j < possibleReactions.length; j++) {
    var reaction = possibleReactions[j];
    if(!item.reactions[reaction]) item.reactions[reaction] = 0;
  }
}

查看下面的工作代码段。

&#13;
&#13;
var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {

  $scope.list = [{
    id: 1,
    title: 'test 1',
    reactions: {
      'like': 7,
      'share': 20,
      'comment': 100
    }
  }, {
    id: 2,
    title: 'test 2',
    reactions: {
      'like': 5,
      'share': 10,
    }
  }, {
    id: 3,
    title: 'test 3',
    reactions: {
      'like': 4,
      'share': 1,
    }
  }, {
    id: 4,
    title: 'test 4',
    reactions: {
      'like': 4,
      'share': 1,
      'comment': 2
    }
  }];
  
  var possibleReactions = ['like', 'share', 'comment'];
  for (var i = 0; i < $scope.list.length; i++) {
    var item = $scope.list[i];
    for (var j = 0; j < possibleReactions.length; j++) {
      var reaction = possibleReactions[j];
      if(!item.reactions[reaction]) item.reactions[reaction] = 0;
    }
  }

  $scope.sorting = {
    field: 'id',
    reverse: false
  };


});
&#13;
<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.5/angular.js" data-semver="1.3.5"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <div>
    <table>
      <tr>
        <th ng-click="sorting.field = 'id'; sorting.reverse = ! sorting.reverse;">ID</th>
        <th ng-click="sorting.field= 'title'; sorting.reverse = ! sorting.reverse;">Title</th>
        <th ng-click="sorting.field = 'reactions.like'; sorting.reverse = ! sorting.reverse;">Likes</th>
        <th ng-click="sorting.field = 'reactions.share'; sorting.reverse = ! sorting.reverse;">Shares</th>
        <th ng-click="sorting.field = 'reactions.comment'; sorting.reverse = ! sorting.reverse;">Comments</th>
      </tr>
      <tr ng-repeat="item in list | orderBy: sorting.field : sorting.reverse">
        <td>
          {{item.id}}
        </td>
        <td>
          {{item.title}}
        </td>
        <td>
          {{item.reactions.like}}
        </td>
        <td>
          {{item.reactions.share}}
        </td>
        <td>
          {{item.reactions.comment}}
        </td>
      </tr>
    </table>
    <div class="hint">
      <p>* Click on table heading in order to sort results.</p>
    </div>
  </div>
</body>

</html>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

你可以做的最常见的事情是关注

<td>
 <span ng-if="item.reactions.comment">{{item.reactions.comment}}</span>
 <span ng-if="!item.reactions.comment">Zero</span>
</td>

如果您找到更精确的方式,请在此处更新。

答案 2 :(得分:0)

创建自己的过滤器

angular
.module("app", [])
.controller("c", function ($scope) {
    $scope.items = [
        {id: 1, name: ""},
        {id: 2, name: "a"},
        {id: 3, name: "b"},
        {id: 4, name: "c"},
        {id: 5, name: ""},
        {id: 6, name: "f"},
        {id: 7, name: ""},
        {id: 8, name: "z"},
    ];
})
.filter("emptyToEnd", function () {
    return function (array, key) {
        var present = array.filter(function (item) {
            return item[key];
        });
        var empty = array.filter(function (item) {
            return !item[key]
        });
        return present.concat(empty);
    };
});

angular.bootstrap(document, ["app"]);

参见工作示例here