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



假设我有以下数据:

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>中构造两个嵌套的列表。

假设我有以下输入,其中用户输入'J'或'J':

<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的艺术家和场地子列表。实时更新是理想的。

如果您不想重构您的数据,可以通过在您的控制器中使用过滤器只获取每个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>

最新更新