Angular 正在获得新的模板语法
更新 2023-10-07:我已将其更新为最终语法形式,使用 @
新的模板语法、内置控制流,告别结构型指令?近年来,Angular 并没有发生太多变化。一些开发者觉得 Angular 很稳定,而另一些开发者则停滞不前。 现在,它正以光速前进。但它究竟会走向何方?
Angular 建议从当前的结构化指令(NgIf、NgForOf、NgSwitch)过渡到新的内置语法。如果您尚未关注RFC(征求意见稿),请先关注。与此同时,我将帮助您了解即将推出的内容。
改进控制流程
Angular 团队的目标是用更现代、类似宏的语法取代现有的结构型指令(NgIf、NgForOf 和 NgSwitch )。虽然结构型指令不会完全消失,但其概念仍将保留——这种编写模板的新方式将成为首选。它向后兼容,并且在一段时间内,您将能够在不同的文件中同时使用新旧模板样式。
改变的目的是为了提高可读性,并提供更顺畅的方式来适应前端世界的更广泛的受众。
前
Angular 中的trackByFunction是一个自定义函数,用于在使用 迭代大型集合时优化性能。在当前语法中,它只需要一个函数,而在新的方式下,*ngFor
它只需要属性即可工作。
Angular 将根据每个项目的id而不是其标识来跟踪集合中的更改。当集合中的项目具有唯一的 id 时,这很有用,可以提高集合更新时的效率。
trackByFunction(index, item) {
return item.id;
}
<div *ngFor="let item of items; index as idx; trackBy: trackByFunction">
Item #{{ idx }}: {{ item.name }}
</div>
后
@for (item of items; track item.id; let idx = $index, let e = $even)
{
Item #{{ idx }}: {{ item.name }}
}
这种新语法在行视图中保留了几个隐式变量,例如$index、$first、$last、$even 和 $odd。这些变量可以直接使用,也可以使用 let 语句为其设置别名。新语法还强调使用 track for 循环来提升性能,并通过强制跟踪来优化列表差异比较。
@for (item of items; track item.id)
{
{{ item }}
}
@empty
{
There were no items in the list.
}
引入的一项关键功能是“空”块,它允许开发人员在列表中没有项目时显示模板。此外,Angular 正在改变其处理列表差异的方式。Angular 将不再使用可自定义的 IterableDiffers,而是提供一种新的优化算法来提高性能。
If-Else 块
如果您发现使用ng-container和ng-template以及结构指令的原始方式*ngIf
不够直观 - 新的控制流可能会解决您的麻烦。
之前(理论上)
<ng-container *ngIf="cond.expr; else elseBlock">
Main case was true!
</ng-container>
<ng-template #elseBlock>
<ng-container *ngIf="other.expr; else finalElseBlock">
Extra case was true!
</ng-container>
</ng-template>
<ng-template #finalElseBlock>
False case!
</ng-template>
后
@if (cond.expr)
{
Main case was true!
}
@else if (other.expr)
{
Extra case was true!
}
@else
{
False case!
}
开关块
“switch” 代码块取代了之前的版本*ngSwitch
。据说新的编写方式带来了诸多好处,例如增强了模板类型检查,并且不再需要容器元素来保存条件表达式。以下是它的简要概述:
@switch (condition)
{
@case (caseA)
{
Case A.
}
@case (caseB)
{
Case B.
}
@default
{
Default case.
}
}
那么移民呢?
迁移到新语法的过程有望相对顺利。Angular团队正在制定一个自动化迁移方案,以便从旧语法转换为新语法。然而,开发者可能需要谨慎对待其应用程序中使用的任何自定义差异算法,因为它可能会影响新 for 指令的行为。
未来机遇
Angular 团队计划扩展此新语法,以适应更多 JS 循环风格,包括异步迭代和 for-in 循环。未来的潜在改进还包括虚拟滚动和解构支持。
还有另一个 RFC 展示了新功能的实际应用——该功能基于新的内置控制流。请查看延迟加载的 RFC 文档
常见问题回顾
让我们快速解决开发人员可能对这种新的控制流语法存在的一些常见问题:
-
现有的结构型指令:现有的结构型指令(例如 NgIf)将继续有效。不过,Angular 强烈建议开发者切换到新的语法。
-
结构指令概念:它不会被删除并且仍然是 Angular 中的一个重要特性。
-
语法突出显示:是的,Angular 语言服务将突出显示新控制流块中的关键字和表达式。
-
对查询结果的影响:新的控制流不会影响查询结果。
-
需要导入新的控制流:否,它将内置于模板语言中并自动提供给所有组件。
-
性能:新的控制流可能会带来一些改进,特别是对于“for”和 diffing。
-
自定义块组和指令:目前,新语法不支持库定义自定义块组,并且您不能向新的控制流块添加指令。
你怎么认为?
这项拟议的语法更改将影响您编写模板的方式。您认为有必要吗?这项更改是否会改善您的 DX,并吸引之前喜欢使用其他框架的新开发人员加入?
我主要关注的是过渡期。我们对响应式原语进行了重大修改,引入了 Signals ,现在又引入了新的模板语法。这些变化无疑将共同描绘出一幅尚未揭晓的宏伟蓝图。未来一段时间,Angular 开发者将会拥有更多处理响应式的选项:RxJS、Signals、Promises、变更检测(zone.js)以及两种编写模板的方式。
完全过渡到新的愿景肯定需要很长时间,而且不可能加快这个过程。现在的问题是,这些进步的代价是否值得我们最终获得的结果?
请务必让我知道并进行讨论!
我希望你喜欢我的文章!
如果你也喜欢我在Twitter上的内容,那你可能也会喜欢。我正在 Twitter 上与 GDE 和行业专家一起直播 Angular 的交流!你可以参与直播、提问,或者观看短片回放 :)
如果你感兴趣的话,可以在Twitter上关注我@DanielGlejzner——这对我很有帮助 :)。谢谢!
哦不!我的咖啡杯空了 :(……
如果你想续杯,尽管来吧 :) https://ko-fi.com/danielglejzner