Angular.js ng-repeat через несколько tr

125

Я использую Angular.js для приложения, которое использует скрытые trs для имитации эффекта выдвижения путем отображения tr и скольжения вниз по div в td ниже. Этот процесс работал фантастически с использованием knockout.js при итерации по массиву этих строк, потому что я мог использовать <!-- ko:foreach -->оба элемента tr.

При использовании angular ng-repeatнеобходимо применить к элементу html, что означает, что я не могу повторить эти двойные строки стандартными методами. Моим первым ответом на это было создание директивы для представления этих двойных trs, но этого не хватило, потому что шаблоны директив должны иметь один корневой элемент, а у меня два ( <tr></tr><tr></tr>).

Если кто-нибудь с опытом работы с ng-repeat и angular, который взломал это, может объяснить, как решить эту проблему, я был бы очень признателен.

(Я также должен отметить, что прикрепление ng-repeatк tbody - это вариант, но это создает несколько tbodys, и я предполагаю, что это плохая форма для стандартного HTML, хотя поправьте меня, если я ошибаюсь)

thegreenpizza
источник

Ответы:

169

Использование ng-repeaton tbodyкажется допустимым, см. Этот пост .

Также быстрый тест с помощью валидатора html допускает наличие нескольких tbodyэлементов в одной таблице.

Обновление: по крайней мере, в Angular 1.2 есть ng-repeat-startи, ng-repeat-endпозволяющие повторять серию элементов. См. Документацию для получения дополнительной информации и спасибо @Onite за комментарий!

Gloopy
источник
Фантастика. У меня была та же проблема, и я действительно обсуждал это, но я думал, что это никогда не сработает, просто повторяя тег tbody. Спасибо!
Халил Раванна
12
Сейчас это немного постфактум, но Angular 1.2 представил директивы ng-repeat-start и ng-repeat-end, чтобы вы могли перебирать несколько элементов.
Onite
1
@Onite Сейчас это намного позже, и я использую AS 1.5, но не знал о добавленных функциях -end и -start в ng-repeat. Вы указали мне туда, поэтому никогда не извиняйтесь за добавление информации в ответ.
Невилл
1
URL-адрес для документации ng repeat неверен, но изменение не превышает шести символов, поэтому я не могу отредактировать его, не добавляя просто бесполезное мета-редактирование. Правильный URL-адрес должен быть docs.angularjs.org/api/ng/ directive / ngRepeat
Билл Роулинсон
35

Разработчик AngularJS @ igor-minar ответил на это в Angular.js ng-repeat для нескольких элементов .

Мишко Хевери недавно реализовал надлежащую поддержку через ng-repeat-startи ng-repeat-end. Это улучшение не было выпущено в версиях 1.0.7 (стабильная) и 1.1.5 (нестабильная).

Обновить

Теперь это доступно в 1.2.0rc1. Ознакомьтесь с официальной документацией и этим скринкастом Джона Линдквиста.

Энсон
источник
Он упоминает об этом в прямом эфире встречи Angular от 11 июня 2013 года. С нетерпением жду этой и других функций в Angular 1.1.5+ и Angular 2.0.
thegreenpizza
Я указываю на 1.1.5 на cdnjs cdn, и это не работает. //cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js знаете ли вы, в какой версии он должен быть доступен?
Shanimal
Верно, не был выпущен в версии 1.1.5, поэтому посмотрите версию 1.1.6 (или, скорее всего, 1.2.0), которая скоро появится. Вот обязательство Мишко следить за выпуском: github.com/angular/angular.js/commit/…
Ансон
Также приятно отметить, что это работает для всех директив, а не только для ngRepeat;)
7hi4g0
4

Наличие нескольких элементов может быть допустимым, но если вы пытаетесь построить прокручиваемую сетку с фиксированными верхними и нижними колонтитулами, следующее может не сработать. Этот код предполагает следующие CSS, jquery и AngularJS.

HTML

<table id="tablegrid_ko">
        <thead>
            <tr>
                <th>
                   Product Title
                </th>
                <th>
                </th>
            </tr>
        </thead>

        <tbody ng-repeat="item in itemList">
            <tr ng-repeat="itemUnit in item.itemUnit">
                <td>{{itemUnit.Name}}</td>
            </tr>
        </tbody>
</table>

CSS для создания фиксированного верхнего / нижнего колонтитула для прокручиваемой сетки таблицы

#tablegrid_ko {
    max-height: 450px;    
}
#tablegrid_ko
{
border-width: 0 0 1px 1px;
border-spacing: 0;
border-collapse: collapse;
border-style: solid;
}

#tablegrid_ko td, #tablegrid_ko th
{
margin: 0;
padding: 4px;
border-width: 1px 1px 0 0;
border-style: solid;
}


#tablegrid_ko{border-collapse:separate}
#tablegrid_ko tfoot,#tablegrid_ko thead{z-index:1}
#tablegrid_ko tbody{z-index:0}
#tablegrid_ko tr{height:20px}
#tablegrid_ko tr >td,#tablegrid_ko tr >th{
border-width:1px;border-style:outset;height:20px;
max-height:20px;xwidth:45px;xmin-width:45px;xmax-width:45px;white-space:nowrap;overflow:hidden;padding:3px}

#tablegrid_ko tr >th{
background-color:#999;border-color:#2c85b1 #18475f #18475f #2c85b1;color:#fff;font-weight:bold}
#tablegrid_ko tr >td{background-color:#fff}
#tablegrid_ko tr:nth-child(odd)>td{background-color:#f3f3f3;border-color:#fff #e6e6e6 #e6e6e6 #fff}
#tablegrid_ko tr:nth-child(even)>td{background-color:#ddd;border-color:#eaeaea #d0d0d0 #d0d0d0 #eaeaea}

div.scrollable-table-wrapper{
background:#268;border:1px solid #268;
display:inline-block;height:285px;min-height:285px;
max-height:285px;width:550px;position:relative;overflow:hidden;padding:26px 0}

div.scrollable-table-wrapper table{position:static}
div.scrollable-table-wrapper tfoot,div.scrollable-table-wrapper thead{position:absolute}
div.scrollable-table-wrapper thead{left:0;top:0}
div.scrollable-table-wrapper tfoot{left:0;bottom:0}
div.scrollable-table-wrapper tbody{display:block;position:relative;overflow-y:scroll;height:283px;width:550px}

Jquery для привязки горизонтальной прокрутки tbody, это не работает, потому что tbody повторяется во время ng-repeat.

$(function ($) {

$.fn.tablegrid = function () {


        var $table = $(this);
        var $thead = $table.find('thead');
        var $tbody = $table.find('tbody');
        var $tfoot = $table.find('tfoot');

        $table.wrap("<div class='scrollable-table-wrapper'></div>");

        $tbody.bind('scroll', function (ev) {
            var $css = { 'left': -ev.target.scrollLeft };
            $thead.css($css);
            //$tfoot.css($css);
        });


    }; // plugin function



}(jQuery));
phanf
источник
0

Вы можете сделать это таким образом, как я показал в этом ответе: https://stackoverflow.com/a/26420732/769900

<tr ng-repeat="m in myData">
   <td>{{m.Name}}</td>
   <td>{{m.LastName}}</td>

   <td ng-if="$first" rowspan="{{myData.length}}">
       <ul>
           <li ng-repeat="d in days">
               {{d.hours}}
           </li>
       </ul>
   </td> 
</tr>
Джефф Тиан
источник