Angularjs: ng-repeat and ng-switch on tr tags
Asked Answered
C

2

9

I'm trying to use AngularJS to create a table of a list of events. But each event has a type, and events of different types have drastically different contents, and some types also generate more than one row.

In a perfect world, I'd do this:

<tbody>
  <ng-repeat="event in events">
    <ng-switch on="event.type">
      <ng-switch-when="type1">
        <tr>
          ...
        </tr>
        <tr>
          ...
        </tr>
      </ng-switch-when>
      <ng-switch-when="type2">
        <tr>
          ...
        </tr>
      </ng-switch-when>
      ...
    </ng-switch>
  </ng-repeat>
</tbody>

but this won't work because most browsers will discard or relocate the ng tags to enforce that the tbody only contains trs.

The only solution I've seen to related problem (How to use ng-repeat without an html element) is to have multiple tbody elements; I'd prefer not to do that, but even if I do this, giving the tbody the ng-repeat and ng-switch attributes, I still have the problem that I can't wrap multiple trs in a single ng-switch-when.

Is there a way to do this in AngularJS, or is this impossible?

Coppola answered 27/1, 2013 at 13:47 Comment(0)
G
1

Maybe the best option would be a directive that generates the appropriate markup based on your type1/type2?

You could probably also do it with ng-hide/ng-show, though that would generate extra unnecessary markup

Guth answered 28/1, 2013 at 19:45 Comment(2)
I suppose I could create a directive, but I'd have to create directives for all the table markup, since the browser parses the DOM before AngularJS processes directives - if I put some <my-tr> directive inside a <table> tag, it'll get shifted to the outside of the table. So I think I'd have to build a slew of directives for table, tbody, tr, th, and td.Coppola
Another option that might work better would be to put your ng-repeat on the tr element, and then use nested tables within each row. and ng-switch on the row contents, but in either case have the contents of the repeated row always just be a single tdGuth
T
2

I've run into this problem, best advice is don't use table:

just do a parent div id with * ammount of child div classes just like they are tr's and td's...

i haven't checked this in angular source but i'm assuming that the table elements aren't intertwined somehow, who knows..

Tervalent answered 27/1, 2013 at 14:45 Comment(1)
Yeah, except sometimes you really do need a table. After all these years, there's still not another reliable way to allow for auto-sized columns of equal width that cross spanned rows. And besides, Angular claims to be the most HTML-in-spirit framework around. To hit a common use case where the answer is "you can't use markup that's been part of HTML since 1.0"... something is wrong.Bystander
G
1

Maybe the best option would be a directive that generates the appropriate markup based on your type1/type2?

You could probably also do it with ng-hide/ng-show, though that would generate extra unnecessary markup

Guth answered 28/1, 2013 at 19:45 Comment(2)
I suppose I could create a directive, but I'd have to create directives for all the table markup, since the browser parses the DOM before AngularJS processes directives - if I put some <my-tr> directive inside a <table> tag, it'll get shifted to the outside of the table. So I think I'd have to build a slew of directives for table, tbody, tr, th, and td.Coppola
Another option that might work better would be to put your ng-repeat on the tr element, and then use nested tables within each row. and ng-switch on the row contents, but in either case have the contents of the repeated row always just be a single tdGuth

© 2022 - 2024 — McMap. All rights reserved.