Angular 复兴:利用 WebStorm 探索新功能
Angular 17 已经推出,标志着框架的又一次重大飞跃。 此版本引入了一系列新功能和增强功能,有望简化开发体验。 如需详尽的更新列表,请参阅 Angular 博客的全面概述。 本文重点关注正在重塑 Angular 应用开发方式的语法和 API 变化:独立组件、信号和新的控制流。
WebStorm 团队付出了巨大努力,在已经发布的 WebStorm 2023.3 中为 Angular 17 提供了关键支持。 此版本还附带一系列有助于改进现代 Angular API 体验的实用检查和快速修复,本文也将涉及。
独立组件
独立组件背后的主要思想是其自我包含性质,因此它们不应该在某些 NgModule 中声明。 独立方式减少了样板代码并使组件更可重用。 从 Angular v17 开始,此方式为默认推荐。
根据此建议,WebStorm 2023.3 中的新 Angular 项目向导包含一个使用独立方式引导应用程序的默认选项:

在这种情况下,生成的应用程序将不包含任何 NgModule,ng generate 命令默认将生成独立组件,在组件的元数据中有效设置 standalone: true:
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-button',
standalone: true, // <---- that's how standalone components are declared
imports: [CommonModule],
templateUrl: './button.component.html',
styleUrl: './button.component.css'
})
export class ButtonComponent {
}
独立组件的 imports 属性用于列出其依赖项。 通常建议避免导入整个模块,因为这会抵消摇树 (tree-shaking) 的好处。 相反,最好精细导入当前组件中使用的组件、指令和管道。 WebStorm 凭借其自动导入机制提供帮助:

即使您的应用是在未使用 --standalone 标志的情况下创建的,并且包含模块,您仍然可以使用 --standalone 标志通过 Angular CLI(从 v15 开始)生成独立组件。 这本质上意味着独立组件可以逐步采用到代码库中。
WebStorm 提供了一种通过 GUI 调用 Angular CLI 命令的便捷方式。 右键点击项目树中的目标文件夹,点击 New(新建),然后选择 Angular Schematic(Angular 原理图):

接下来,从选项列表中选择 Component(组件)。 Generate Component(生成组件)对话框基于所选 CLI 命令为实参提供了自动补全:

如果将某些组件迁移为独立组件,则应将其从模块的 declarations 中移除。 但相反,您可能希望将其放入模块的 imports 中以在非独立组件中使用。 WebStorm 为此提供了一个快速修复:

此前,IDE 会运行检查来识别既不独立也不属于任何模块的组件:

现在,IDE 的默认建议是使组件独立:

对于迁移,Angular CLI 提供了一种便捷的方式,可以使用 @angular/core:standalone 命令将整个项目或其部分迁移到独立 API。 此命令也可以通过 WebStorm 中的 Angular Schematics(Angular 原理图)操作启动。
在开始这个过程之前,务必确保您当前的所有工作都已提交。 如果迁移过程中出现问题,这可以让您还原到先前的状态。 此外,请记住,对于复杂的应用程序,迁移成功完成后仍然需要仔细检查更改。
信号
根据 Angular 的文档:
信号是一个反应性系统,精细跟踪整个应用程序中状态的使用方式和位置。 这让 Angular 框架能够优化渲染更新,增强应用程序效率。
为了描述反应性此前在 Angular 中的运作方式,我们可以看看它对 zone.js 库的使用。 特别是,zone.js 修补浏览器 API 以侦听可能影响数据的事件。 然后,Angular 运行自上而下的全局更改检测机制来对这些事件做出反应。 这种机制使 UI 与应用状态保持同步,无需显式触发更改,但这种方式有时会导致性能问题和难以跟踪的问题。
此外,应用状态需要内置反应式 API,特别是在派生状态方面。 您可以阅读信号 RFC 和先前讨论,详细了解其背后的动机和设计决策。
那么,什么是信号?
信号是值的包装器,会在值发生变化时通知相关使用者。 信号可以包含从基元到复杂数据结构的任何值。
为方便您操作,WebStorm 提供了一组实时模板来协助创建信号和计算状态:

此外,您还可以直接从模板即时创建信号:

WebStorm 带有信号颜色高亮显示,您也可以根据需要进行自定义。 为此,转到 Settings | Editor | Color Scheme | Angular Template | Signal(设置 | 编辑器 | 配色方案 | Angular 模板 | 信号):

使用不同颜色的信号有助于减少认知负担,也有助于减少未调用模板中函数表达式的常见错误(也就是缺少 `()`)。
控制流
以前,在 Angular 模板中,您只能使用指令有条件地渲染应用程序的部分,或者渲染列表。 这是管理模板动态方面的方式。 以下示例使用 *ngIf 和 *ngSwitch 指令有条件地显示身份验证状态和用户角色:
<div *ngIf="isAuthenticated; else anonymous">
Role:
<div [ngSwitch]="accessLevel">
<div *ngSwitchCase="'admin'">Admin</div>
<div *ngSwitchCase="'moderator'">Moderator</div>
<div *ngSwitchDefault>Guest</div>
</div>
</div>
<ng-template #anonymous>
The user is not authenticated
</ng-template>
Angular 17 引入了一种新的控制流语法,旨在替换指令。 它更符合人体工学,语法上与 JavaScript 类似:
@if (isAuthenticated) {
<div>
Role:
<div>
@switch (accessLevel) {
@case ('admin') {
<div>Admin</div>
}
@case ('moderator') {
<div>Moderator</div>
}
@default {
<div>Guest</div>
}
}
</div>
</div>
} @else {
The user is not authenticated
}
新控制流还提供了更好的类型检查,因为现在可以在条件分支内缩小类型。
对于循环,新控制流将代码从这样:
<ng-container *ngFor="let article of articleList()"> <app-article [article]="article"></app-article> </ng-container>
……变成这样:
@for (article of articleList(); track article.id) {
<app-article [article]="article"></app-article>
} @empty {
no articles
}
请注意,在 @for 块中必须指定 track,以避免常见性能问题。 与 *ngFor 中的 trackBy 不同,它允许使用表达式和跟踪函数。 如果集合没有条目,还有一个方便的 @empty 块来渲染元素。
Angular 17 的主要功能之一是可推迟视图。 虽然与控制流并不严格相关,但可推迟视图利用了相同的 @block 语法,并且没有相应指令:
@defer (on viewport) {
<article/>
} @loading {
Loading Article…
} @error {
Error occured
} @placeholder {
<img src="placeholder.png">
}
可推迟视图更精细地提供了延迟加载的好处(此功能过去与 Angular 路由器紧密耦合),允许仅延迟加载视图的单个部分。 它还具有路由延迟加载无法提供的自定义功能。 由此,可推迟视图允许您指定 on 和 when 条件。 再加上 Angular 框架提供的预定义条件,例如 on viewport、on idle、on interaction、on hover、on immediate 和 on timer,您可以定义非常具体的加载行为。
与独立组件一样,可以使用一个 CLI 命令将模板迁移到新控制流:@angular/core:control-flow。
WebStorm 2023.3 提供了对新控制流和块语法的初步支持。 我们计划在后续版本中添加进一步增强。
结论
Angular 17 充满了令人期待的新功能,是名副其实的“Angular 复兴”。 WebStorm 2023.3 引入了针对这些新 API 的支持,并且该版本包括许多实用的快速修复以及增强的严格模板检查。 我们将在后续版本中进一步改进控制流支持。 敬请关注更多动态!
WebStorm 团队
本博文英文原作者: