使用Angular ng-repeat迭代非均匀的对象数组

时间:2015-10-11 18:01:39

标签: javascript html angularjs angularjs-directive angularjs-filter

假设我有以下数据:

sampleData = [{'artist': 'John', 'id': 1}, {'artist': 'John', 'id': 2},
{'artist': 'Tim', 'id': 3}, {'artist': 'Jimmy', 'id': 4}, {'venue': 'Rock club', 'id':1}, {'venue': 'Rock club', 'id': 2}, {'venue': 'Tonys', 'id': 3}]

这些数据可以在我的控制器中找到,并且不会发生变化。我想要做的是在主<ul>内构建两个嵌套列表。

鉴于我有以下输入,用户在哪里输入&#39; J&#39;或者&#39; j&#39;:

<input ng-model="query" type="text" placeholder="Filter by">

这是我想用ng-repeat渲染的内容(除非我不必使用ng-repeat):

<ul>
  <h1>artist</h1>
  <li>
    <ul>
      <li>John (There are two 2 Johns)</li>
      <li>Jimmy</li>
    </ul>
  </li>
  <li>
    <ul>
    <h1>Venue</h1>
      <li>Jock Club (There are two 2 Jock Club)</li>
    </ul>
  </li>
</ul>

最初,我尝试编写一个客户过滤器,该过滤器从过滤列表中获取结果并操纵数据。 Angular对我的过滤器并不满意,因为我过多地修改原始数据,因此我收到了无限的摘要循环。所以现在我回到正方形试图决定是否最好用指令或过滤器完成。我怀疑我需要在我的控制器或指令中重构我的数据以获得我的预期结果。同样,我的预期结果将是根据用户输入内容的sampleData的艺术家和场地子列表进行过滤。实时更新是理想的。

1 个答案:

答案 0 :(得分:2)

如果您不想重新构建数据,可以通过让控制器中的函数使用过滤器来获取每个ng-repeat所需的项目来实现:

在控制器中:

var sampleData = [...];
$scope.query = '';

$scope.getArtists = function () {
   return $filter('filter')(sampleData, function (item) {
       return item.hasOwnProperty('artist') && item.artist.indexOf($scope.query) > -1; 
   });
};

$scope.getVenues = function () {
   return $filter('filter')(sampleData, function (item) {
       return item.hasOwnProperty('venue') && item.venue.indexOf($scope.query) > -1;  
   });
};

HTML:

<input ng-model="query" type="text" placeholder="Filter by">
<ul>
    <li ng-repeat="artist in getArtists()"></li>
</ul>
<ul>
    <li ng-repeat="venue in getVenues()"></li>
</ul>

----------

但是,预先重组数据可能会更好,这样您就可以更有效地使用单一功能迭代场地和艺术家:

在控制器中:

var sampleData = [...];
$scope.query = '';
$scope.artists = [];
$scope.venues = [];

angular.forEach(sampleData, function (item) {
    if (item.hasOwnProperty('artist') {
        $scope.artists.push({
            id: item.id,
            name: item.artist
        });
    });
    else if (item.hasOwnProperty('venue') {
        $scope.venues.push({
            id: item.id,
            name: item.venue
        });
    });
});

$scope.getMatching = function (items, query) {
    return $filter('filter')(items, function (item) {
        return (item.name.indexOf(query) > -1); 
    });
};

HTML:

<input ng-model="query" type="text" placeholder="Filter by">
<ul>
    <li ng-repeat="artist in getMatching(artists, query)"></li>
</ul>
<ul>
    <li ng-repeat="venue in getMatching(venues, query)"></li>
</ul>