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 团队
本博文英文原作者: