type
status
date
slug
summary
tags
category
icon
password
Angular 在这个月发布了 17 版本,带来了许多新的功能,其中之一就是在模板中内置了新的控制流(Control Flow)。
控制流是一种将流程控制直接写入模板的新声明性语法,从而无须使用
*ngIf、*ngFor 和 *ngSwitch 这种基于指令(Directive)的控制流。不知道大家有没有这种感觉,在使用基于指令的控制流时,经常会忘记具体的语法,需要反复查看文档,而新的控制流语法变得很简单,也更容易记住。本篇文章将通过重构一个简单的项目,来展示一下如何将基于指令的控制流,转换为新的内置控制流写法。
项目设置
在创建项目之前,首先需要确保安装了最新版本的 Angular cli。
之后创建一个新项目:
我们的示例模板代码内容如下:
效果图:

在应用加载时,会随机从
users、posts 和 photos 中获取一种数据。点击按钮会重新随机获取(数据来自 jsonplaceholder)。在获取过程中显示 No data or loading...,如果获取到 users 或者 posts,会渲染出列表,否则显示 Unknown Data Type...。@if
首先让我们从替换
*ngIf 开始。从模板代码中可以看到,我们使用
*ngIf 来判断当前是否有数据,有的话渲染对应的内容,没有的话渲染 #noData 模板。使用新的内置语法替换之后如下:
与基于指令的
*ngIf 相比,有以下几个优点:- 可以直接使用
@else,不需要声明额外的模板变量。
- 支持
@else if语法,能够判断更多的情况,基于指令的写法是做不到的。
- 新的语法无须导入
CommonModule或者ngIf指令,方便使用。
@switch
接下来我们替换
*ngSwitch。我们在模板代码中,通过获取到的数据类型,来显示不同的内容。只支持 users 或者 posts,否则渲染
*ngSwitchDefault 部分。使用新的内置语法替换之后写法如下:
新的语法有一个最大的优点就是可以做到类型收窄。

通过上面的图可以看到,在
@case ('posts') 分支下,typescript 能够推断出 payload 对应的类型为 Post[],同理,如果我们查看 @case('users') 下的 payload,类型就是 User[]。这在 *ngSwitch 中是不可能做到的。@for
最后是
*ngFor,我们以 app-user-list 为例。我们使用
*ngFor 渲染了一个 users 列表,并且提供了 trackBy 函数,以及将 index 赋值给了 i 变量。新的内置语法写法如下:
需要注意的是,
@for 必须提供 track 部分,这个对性能优化很重要,可以像上面代码一样,或者直接 track $index 也是可以的。@for 还有个伙伴 @empty,我们在渲染列表时,有时候会先判断列表长度是不是为 0,这时候会用到 @if,比如这种写法:这种情况可以使用
@empty,省去 @if 和 @else。总结
总体来说,新的内置语法与 js 语法更相似了,变得更加直观,简化了使用方式。
并且根据 Angular 团队的说法,内置控制流减少了运行时的占用空间,性能更好。
如果你的项目有升级 Angular 到最新版本的打算,那就赶快体验起来吧!
- Author:大胖猫
- URL:http://preview.tangly1024.com/article/223f4632-e87d-8049-96e8-d4c283d2e50c
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!









