Today I encountered some weird behaviour when I tried to iterate over a list of lists with ngFor, when the outer ngFor loop is not embedded in a structural directive, but explicitly written out as directives on a <template>.
I reproduced the issue in this standalone example component:
import 'dart:math';
import 'package:angular/angular.dart';
@Component(
selector: 'demo-component',
template: '''
<div>
<button (click)="addList()">add list</button>
<button (click)="addElements()">add elements</button>
</div>
<ul>
<template ngFor let-outer [ngForOf]="lists">
<li *ngFor="let number of outer">
{{number}}
</li>
</template>
</ul>
''',
directives: [coreDirectives],
)
class DemoComponent {
final List<List<int>> lists = [
[1]
];
/// Adds a new inner list to [lists].
void addList() => lists.add(
List.generate(lists.first.length, (i) => _valueFor(lists.length, i)));
/// Adds a new element to each inner list in [lists].
void addElements() {
var i = 0;
for (final inner in lists) {
inner.add(_valueFor(i++, inner.length));
}
}
int _valueFor(int listIndex, int elementIndex) =>
(elementIndex + 1) * pow(10, listIndex);
}
By clicking on the two buttons, you can generate a list of lists of numbers of the following pattern:
[
[1, 2, 3],
[10, 20, 30],
[100, 200, 300]
]
The template should render a flattened list, like this:
- 1
- 2
- 3
- 10
- 20
- 30
- 100
- 200
- 300
However, when you add new inner lists (e.g. [1000, 2000, 3000]), the corresponding HTML is rendered at the wrong place – not at the end of the flattened list, but somewhere in the middle. (I haven't figured out the exact pattern where the new nodes are placed. The position changes depending on which button you press first)
I use Angular version 5.0.0, Dart 2.0.0, and Chrome Version 70.0.3538.77.