ChatGPT解决这个技术问题 Extra ChatGPT

Angular.js ng-repeat across multiple tr's

I am using Angular.js for an application that uses hidden trs to simulate a sliding out effect by showing the tr and sliding down the div in the td below. This process worked fantastically using knockout.js when iterating over an array of these rows, because I could use <!-- ko:foreach --> around both tr elements.

With angular, ng-repeat must be applied to an html element, meaning I cannot seem to repeat these double rows using standard methods. My first response to this was to create a directive to represent these double trs, but that fell short because directive templates must have a single root element, but I have two (<tr></tr><tr></tr>).

If anyone with experience with ng-repeat and angular who has cracked this can explain how to solve this problem, I would be greatly appreciative.

(I should also note that attaching ng-repeat to the tbody is an option, but this produces multiple tbodys, and I am assuming that is bad form for standard HTML, although correct me if I'm wrong)


C
Community

Using ng-repeat on tbody appears to be valid see this post.

Also a quick test through an html validator allowed multiple tbody elements in the same table.

Update: As of at least Angular 1.2 there is an ng-repeat-start and ng-repeat-end to allow repeating a series of elements. See the documentation for more information and thanks to @Onite for the comment!


Fantastic. I had the same problem and actually debated doing this but I thought it would never work just iterating on the tbody tag. Thanks!
It's a bit after the fact now, but Angular 1.2 introduced the ng-repeat-start and ng-repeat-end directives to allow you to iterate over multiple elements.
@Onite It is much later now and I'm using AS 1.5 but didn't know about the added -end and -start functionality of ng-repeat. You pointed my there so never apologise for adding info to an answer.
The url for the ng repeat documentation is wrong but the change isn't more than six characters so I can't edit it without just adding some useless meta edit.. The correct url should be docs.angularjs.org/api/ng/directive/ngRepeat
C
Community

AngularJS developer @igor-minar answered this in Angular.js ng-repeat across multiple elements.

Miško Hevery recently implemented proper support via ng-repeat-start and ng-repeat-end. This enhancement hasn't been released as of 1.0.7 (stable) and 1.1.5 (unstable).

Update

This is now available in 1.2.0rc1. Check out the official docs and this screencast by John Lindquist.


He mentions this in the Angular meetup livestream from June 11th, 2013. Looking forward to this and other features in Angular 1.1.5+ & Angular 2.0.
I'm pointing to the 1.1.5 on cdnjs cdn and this isn't working. //cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js do you know what version this is supposed to be available in?
Correct, wasn't released as of 1.1.5, so watch 1.1.6 (or very likely 1.2.0) to land soon. Here is Miško's commit to watch for release: github.com/angular/angular.js/commit/…
Also good to notice that this works for every directive, not only ngRepeat ;)
p
phanf

Having multiple elements might be valid but if you're trying to build a scrollable grid with fixed header / footers, the follow could will not work. This code assumes the following CSS, jquery and 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 to build fixed header/footer for scrollable table grid

#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 to bind horizontal scrolling of tbody, this does not work because tbody repeats during 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));

C
Community

You can do it in this way, as I showed in this answer: 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>