It turns out this is not a bug in Angular... it's actually being caused by 
weird behaviour in the browser. It doesn't like the <ng-repeat> tags inside 
<table> so during parsing of HTML it moves them *outside* the <table> in 
the DOM before Angular fires up. By the time Angular gets to see the page 
structure, it's too late - the DOM is borked. This isn't something that can 
be fixed in Angular.

So I guess I can try a couple of things to flatten the structure (I have 
three approaches I can try) -- it's possible the "recursion" error I was 
seeing was caused by something I did in the code in my earlier attempts, so 
I'll give it another shot and see if I can make it work. If not, I'll just 
have to tell the client that if he wants this display it'll have to be done 
with something other than a table.

On Saturday, March 11, 2017 at 3:43:41 PM UTC-7, Pete Ford wrote:
>
> I did try that -- I got an Angular exception (something about a potential 
> infinite loop, if I remember correctly). I should point out that my example 
> is a simplification of the real page; in the real thing there are controls 
> to select the items to be included in the top-level list, so the list can 
> change dynamically. I think this was causing some recursion in event 
> handlers, or something like that.
>
> In any case, I'd rather avoid a messy workaround if I can. As I understand 
> it, there's no reason why the ng-repeat tag shouldn't work inside a table 
> so long as it doesn't generate any HTML tags that are invalid inside 
> <tbody> tags. It really should just replicate the markup enclosed in the 
> <ng-repeat>, I thought, but using the Chrome Developer Tools to inspect the 
> page shows that it's generating nothing other than a <!-- ng-repeat .... 
> --> comment inside the <tbody>. I didn't see anything in the documentation 
> to suggest that ng-repeat can't be used inside a table, which to me implies 
> that this is a bug.
>
> On Sat, Mar 11, 2017 at 3:21 PM, Guilherme Meireles <[email protected]> 
> wrote:
>
>> I recommend you try to flatten your structure to create a row list.
>>
>> Try something like this:
>>
>> var flattedList = itemList.reduce((state, item) => {
>>     return state.concat(item.categoryList.reduce((nestedState, category) 
>> => {
>>         var flattedState = category.commentList.map(comment => ({
>>             item,
>>             category,
>>             comment,
>>         }));
>>         return nestedState.concat(flattedState)
>>     }, []));
>> }, []);
>>
>> //flattedList: {item,category,comment}[]
>>
>> <table>
>>     <thead>
>>         <th>Item</th>
>>         <th>Category</th>
>>         <th>Comment</th>
>>     </thead>
>>     <tbody>
>>         <tr ng-repeat="flatItem in flattedList">
>>             <td>{{ flatItem.item.name }}</td>
>>             <td>{{ flatItem.category.name }}</td>
>>             <td>{{ flatItem.comment }}</td>
>>         </tr>
>>     </tbody>
>> </table>
>>
>> On Saturday, March 11, 2017 at 2:38:47 PM UTC-3, Pete Ford wrote:
>>>
>>> I'm having a similar problem. I have a list of items, each of which has 
>>> a name and one or more "category" objects attached; each category has a 
>>> name and zero or more "comment" objects. I need to render this in a table, 
>>> so I have this:
>>>
>>> <table>
>>>   <thead>
>>>     <th>Item</th>
>>>     <th>Category</th>
>>>     <th>Comment</th>
>>>   </thead>
>>>   <tbody>
>>>     <ng-repeat ng-repeat="item in itemList">
>>>       <ng-repeat ng-repeat="category in item.categoryList">
>>>         <tr ng-repeat="comment in category.commentList">
>>>           <td>{{item.name}}</td>
>>>           <td>{{category.name}}</td>
>>>           <td>{{comment}}</td>
>>>         </tr>
>>>       </ng-repeat>
>>>     </ng-repeat>
>>>   </tbody>
>>> </table>
>>>
>>> I expect to see something like this:
>>>
>>> Item  Category  Comment
>>> item1 cat1  comment1
>>> item1 cat1 comment2
>>> item1 cat2 comment1
>>> Item2 cat1 comment1
>>> ...etc.
>>>
>>> This doesn't work; no matter what data is in my list of items, I get an 
>>> empty table. I can show the nested ng-repeat outside a table works -- this 
>>> works exactly the way I expected:
>>>
>>>     <ng-repeat ng-repeat="item in itemList">
>>>       <ng-repeat ng-repeat="category in item.categoryList">
>>>         <p ng-repeat="comment in category.commentList">
>>>           {{item.name}} - {{category.name}} - {{comment}}
>>>         </p>
>>>       ...
>>>
>>> So it looks like you can't use ng-repeat inside a table structure at 
>>> all, although as far as I can see there's no reason why this wouldn't work. 
>>> (I'd prefer to use something other than an HTML table, but it's what the 
>>> client wants so I'm stuck with it.)
>>>
>>> I really need to get this working. I'm using AngularJS 1.5.9 at the 
>>> moment; is this something that's been fixed in a later version?
>>>
>>> On Wednesday, April 29, 2015 at 12:53:07 PM UTC-6, Slava Fomin II wrote:
>>>>
>>>> Hello!
>>>>
>>>> I've encountered an advanced use-case in my practice that I have 
>>>> problems implementing in Angular.js, so I'm in need of assistance.
>>>>
>>>> It is required to render a hierarchical data in a single HTML table.
>>>>
>>>> I've found this Q/A: 
>>>> http://stackoverflow.com/questions/11854514/is-it-possible-to-make-a-tree-view-with-angular
>>>>  
>>>> and decided to use the offered approach, i.e. to extract repeatable part 
>>>> of 
>>>> the table (row) into a separate template and then render it recursively.
>>>>
>>>> The problem is that HTML table has a pretty strict structure (according 
>>>> to the standard): table > tbody > tr > td and I can't add elements in the 
>>>> middle in order to apply some directives to it.
>>>>
>>>> I've extracted the *<tr>* into a separate template and applied a 
>>>> *ngRepeat* to it. In the main template I've applied *ngInclude* to the 
>>>> *tbody*. But where do I place a recursive call with additional 
>>>> *ngInclude*?
>>>>
>>>> To work correctly this *ngInclude* should be a sibling of *<tr>*, but 
>>>> I can't make it a sibling cause *ngRepeat* is applied to the *<tr>*. 
>>>> So in order to make it work I will need another element (parent to both 
>>>> *<tr>* and *ngInclude*) to which I will be able to apply *ngRepeat*, 
>>>> but HTML standard doesn't provide such an element (there is no element to 
>>>> group rows together beside the *tbody* and I don't really want to use 
>>>> it multiple times in the table).
>>>>
>>>> Looks like Angular is fighting with HTML in this use-case instead of 
>>>> cooperating and extending it.
>>>>
>>>> It would be possible to solve this if *ngRepeat* could be used as a 
>>>> separate element like this: *<ng-repeat>*, but it's an *"A"* directive 
>>>> only.
>>>>
>>>> Are there any options here I'm not seeing? How should we approach such 
>>>> category of problems? Maybe Angular could be improved to address such 
>>>> issues?
>>>>
>>>> Thanks!
>>>>
>>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Angular and AngularJS discussion" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected].
>> To post to this group, send email to [email protected].
>> Visit this group at https://groups.google.com/group/angular.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Angular and AngularJS discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Reply via email to