Angular 17+ 全新迭代语法@for
有关新 @for 模板语法的所有功能和最佳实践,以及对现在强制的跟踪功能的解释。
client preview
随着 Angular 17 的发布,新的控制流语法(包括该@for语法)为开发人员带来了更好的体验。
以前,我们需要从@angular/common 导入ngFor指令在 Angular 模板中迭代数组。
但现在,@for内置模板语法简化了模板迭代,为开发人员提供了更直观的循环机制。
它提供了更简洁、性能更安全的体验ngFor,而无需任何额外的导入。
@for中的track
跟踪函数track
用于使 Angular 变化检测机制能够准确地知道在输入数组发生变化后需要在 DOM 中更新哪些项目。跟踪功能告诉 Angular 如何唯一地标识列表中的元素。熟悉vue和react的同学对此并不陌生。这不就是用来diff算法优化的吗。
typescript
@Component({
template: `<ul>
@for (fruit of fruits; track fruit.id) {
<li>{{ fruit }}</li>
}
</ul>`,
})
class CoursesComponent {
fruits = [
{ id: 1, name: "Apple" },
{ id: 2, name: "Banana" },
{ id: 3, name: "Orange" },
];
}
这里我们使用id作为唯一标识传给track
。当然我们还可以给track传函数
typescript
@Component({
template: `<ul>
@for (fruit of fruits; track trackFruit) {
<li>{{ fruit }}</li>
}
</ul>`,
})
class CoursesComponent {
fruits = [
{ id: 1, name: "Apple" },
{ id: 2, name: "Banana" },
{ id: 3, name: "Orange" },
];
trackFruit(index: number, fruit: Fruit) {
return fruit.id;
}
}
可以更灵活的自定义track函数。
@for 与 @empty
在没有@for之前,当迭代数组为空的时候我们需要展示一些提示信息,这是一个很常见的功能。
typescript
@Component({
template: `
<ul>
<ng-container *ngFor="let item of items">
<li>{{ item }}</li>
</ng-container>
<ng-container *ngIf="items.length === 0">
<li>No Data</li>
</ng-container>
</ul>
`,
standalone: true,
imports:[NgForOf, NgIf]
})
class Example {
items = [];
}
我们还需要用到ngIf做单独的判断。但是有了@for以后我们可以这样写
typescript
@Component({
template: `<ul>
@for (item of items; track item) {
<li>{{ item }}</li>
}
@empty {
<li>No Data</li>
}
</ul>`,
})
class Example {
items = [];
}
可以看到新的写法更简洁,代码结构更清晰。
@for 与 可迭代对象
@for不知支持数组的迭代,而是所有的可迭代对象。以下是一个map的例子
typescript
@Component({
template: `<ul>
@for (entry of map; track entry) {
<li>{{ entry[0] }}: {{ entry[1] }}</li>
}
</ul>`,
})
class Example {
map = new Map([
["firstName", "Apple"],
["lastName", "Banana"],
]);
}
我们甚至可以直接遍历一个字符串,因为它也是可迭代的。
@for控制流中的隐式变量
$index
用于记录当前遍历的索引值
typescript
@Component({
template: `<ul>
@for (item of items; track item; let index = $index) {
<li>{{ index }}: {{ item }}</li>
}
</ul>`,
})
class Example {
items = ["Apple", "Banana", "Orange"];
}
$first
保存一个布尔值,指示当前项是否是集合中的第一个项。
$last
保存一个布尔值,指示当前项目是否是集合中的最后一项。
typescript
@Component({
template: `
<ul>
@for (item of items; track item; let first = $first, last = $last) {
<li>{{ item }}: {{ first }}: {{ last }}</li>
}
</ul>
`
})
class Example {
items = ["Apple", "Banana", "Orange"];
}
//Apple: true: false
//Banana: false: false
//Orange: false: true
$odd
保存一个布尔值,指示当前索引是否为奇数:1、3、5...
$even
保存一个布尔值,指示当前索引是否为偶数:0、2、4...
$count
记录了正在循环的 Iterable 元素的总数
用法与上述相同不过多展示了。
使用 Angular CLI 迁移到 @for
git bash
ng generate @angular/core:control-flow
