Фильтровать строки по заголовку столбца

#angularjs #filter #ng-repeat

#angularjs #Фильтр #angularjs-ng-repeat

Вопрос:

Совершенно новый для Angular. Мне нужно создать таблицу, в которой отображаются новости. У каждой новости есть категория, заголовок, подзаголовок, вступление. Мне нужен один столбец для каждой категории:

US International Head1 Head1 Sub1 Sub1 Intro1 Intro1 Head2 Head2 Sub2 Sub2 Intro2 Intro2

В каждой категории всегда будет одинаковое количество элементов

Итак, я получаю уникальный список категорий для создания TH, затем для каждой новости в каждой категории я хочу отобразить tbody с 3 строками (заголовок, подзаголовок, вступление)

Вот мой контроллер JS

 window.myApp = this.angular.module('myApp', []);


function NewsController($scope) {
    $scope.newsItems = [
      { category: 'US', headline: 'US Headline 1', subhead: 'US Subhead 1', intro: 'US Intro 1' },
      { category: 'US', headline: 'US Headline 2', subhead: 'US Subhead 2', intro: 'US Intro 2' },
      { category: 'International', headline: 'International Headline 1', subhead: 'International Subhead 1', intro: 'International Intro 1' },
      { category: 'International', headline: 'International Headline 2', subhead: 'International Subhead 2', intro: 'International Intro 2' }
    ];

    // distinct list of categories
    $scope.categories = $scope.newsItems.reduce(function (sum, item) {
        return (sum.indexOf(item.category) == -1 ? sum.concat(item.category) : sum);
    }, []);
}
  

Вот HTML

 <div ng-app>
<table class="news" ng-controller="NewsController">
    <thead>
        <tr class="section hidden-xs text-danger">
            <!-- Distinct List -->
            <th ng-repeat="category in categories" value="{{category}}">{{ category }}</th>
        </tr>
    </thead>
    <tbody ng-repeat="item in newsItems">
        <tr>
            <td class="">{{ item.headline }}</td>
        </tr>
        <tr>
            <td class="">{{ item.subhead }}</td>
        </tr>
        <tr>
            <td>{{ item.intro }}</td>
        </tr>
    </tbody>
</table>
  

Вот скрипка: http://jsfiddle.net/mark2457/WMzYX/2 /

Я начал думать, что получу первое от каждого в строке 1, второе от каждого для строки 2, но понял, что не знаю, как это сделать. Это просто фиктивные данные. В конечном итоге это, вероятно, будет поступать из двух RSS-каналов. Я мог бы поместить каждую категорию в свой собственный контроллер, но это кажется большим дублированием.

(еще один момент, мне нужно условно добавить классы к элементам th и td (например, вторым th и td нужен дополнительный класс, который обозначает, что then имеет возможность скрытия для адаптивного макета)

В идеале мне бы хотелось, чтобы все это было в отдельном файле, который я мог бы каким-то образом вставить в основной HTML, если это возможно

Может ли кто-нибудь указать мне правильное направление?

Спасибо

Отметить

Комментарии:

1. Сейчас вы используете таблицу для отображения двух списков или многих списков в будущем, которые могут даже различаться по длине. Таблицы в AngularJS очень сложно использовать ng-repeat для отображения этих данных, можете ли вы отказаться от таблиц, скажем, для divs? Это значительно упростило бы ответ

Ответ №1:

Я предполагаю, что вы можете отказаться от использования html table , причина в том, что вы на самом деле пытаетесь отобразить несколько списков данных, которые вы группируете по свойству. Использование table действительно затрудняет выполнение того, что вы просите, потому что из tr вы не можете знать, какую категорию вы должны отображать, поскольку tr не является дочерним элементом заголовка, вы не можете использовать два ng-repeat s внутри друг друга.

 angular.module('news', []);

angular.module('news').controller('NewsController', function($scope) {

    $scope.newsItems = [
      { category: 'US', headline: 'US Headline 1', subhead: 'US Subhead 1', intro: 'US Intro 1' },
      { category: 'US', headline: 'US Headline 2', subhead: 'US Subhead 2', intro: 'US Intro 2' },
      { category: 'International', headline: 'International Headline 1', subhead: 'International Subhead 1', intro: 'International Intro 1' },
      { category: 'International', headline: 'International Headline 2', subhead: 'International Subhead 2', intro: 'International Intro 2' }
    ];

    $scope.newsItemsGrouped = {};
    $scope.newsItems.forEach(function(item){
        $scope.newsItemsGrouped[item.category] = $scope.newsItemsGrouped[item.category] || [];
        $scope.newsItemsGrouped[item.category].push(item);
    });

});  
 .category-list {
    float: left;
    border: 1px solid black;
    margin: 5px;
    padding: 5px;
    width: 250px;
}  
 <html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  </head>
  <body ng-app="news" ng-controller="NewsController">
    <div ng-repeat="(category, items) in newsItemsGrouped" class="category-list">
      <h2>{{ category }}</h2>
      <div ng-repeat="item in items">
        <p>{{ item.headline }}</p>
        <p>{{ item.subhead }}</p>
        <p>{{ item.intro }}</p>
      </div>
    </div>
  </body>
</html>  

Наиболее примечательно, что теперь мы используем два ng-repeat s внутри друг друга, и это newsItemsGrouped сопоставление категорий со списком элементов, входящих в эту категорию. Таким образом, вы можете прочитать категорию и список, теперь, когда у нас есть список для каждой категории, мы можем ng-repeat снова использовать его и отображать свойства каждого элемента.

Группировку вы можете выполнить с помощью простого JavaScript и с помощью некоторого CSS, у вас будет примерно такой макет, как вы указали в примере.

Комментарии:

1. Спасибо за ответ. Я не могу на самом деле удалить таблицы, потому что мне нужно выровнять заголовки, поэтому, если US story 1 — это 5 строк, а Int story 1 — 6 строк, мне нужно начать story 2 в строке 7 для обоих. Я не знаю способа сделать это без таблицы (или добавления пустых строк). Это дало мне некоторые идеи, и я изменил свой контроллер, чтобы возвращать объединенный список, чтобы US1 и Int1 были в одной записи, тогда я мог бы использовать обычный ng-repeat. Еще раз спасибо. Отметить