All Things Web

Angular 复兴:利用 WebStorm 探索新功能

Read this post in other languages:

Angular 17 已经推出,标志着框架的又一次重大飞跃。 此版本引入了一系列新功能和增强功能,有望简化开发体验。 如需详尽的更新列表,请参阅 Angular 博客的全面概述。 本文重点关注正在重塑 Angular 应用开发方式的语法和 API 变化:独立组件、信号和新的控制流。

WebStorm 团队付出了巨大努力,在已经发布的 WebStorm 2023.3 中为 Angular 17 提供了关键支持。 此版本还附带一系列有助于改进现代 Angular API 体验的实用检查和快速修复,本文也将涉及。

独立组件

独立组件背后的主要思想是其自我包含性质,因此它们不应该在某些 NgModule 中声明。 独立方式减少了样板代码并使组件更可重用。 从 Angular v17 开始,此方式为默认推荐。

根据此建议,WebStorm 2023.3 中的新 Angular 项目向导包含一个使用独立方式引导应用程序的默认选项:

Angular17 项目向导

在这种情况下,生成的应用程序将不包含任何 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 凭借其自动导入机制提供帮助:

SC 导入

即使您的应用是在未使用 --standalone 标志的情况下创建的,并且包含模块,您仍然可以使用 --standalone 标志通过 Angular CLI(从 v15 开始)生成独立组件。 这本质上意味着独立组件可以逐步采用到代码库中。

WebStorm 提供了一种通过 GUI 调用 Angular CLI 命令的便捷方式。 右键点击项目树中的目标文件夹,点击 New(新建),然后选择 Angular Schematic(Angular 原理图):

新建原理图

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

组件对话框

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

导入快速修复

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

SC 检查

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

SC 快速修复

对于迁移,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 路由器紧密耦合),允许仅延迟加载视图的单个部分。 它还具有路由延迟加载无法提供的自定义功能。 由此,可推迟视图允许您指定 onwhen 条件。 再加上 Angular 框架提供的预定义条件,例如 on viewporton idleon interactionon hoveron immediateon timer,您可以定义非常具体的加载行为。

与独立组件一样,可以使用一个 CLI 命令将模板迁移到新控制流:@angular/core:control-flow

WebStorm 2023.3 提供了对新控制流和块语法的初步支持。 我们计划在后续版本中添加进一步增强。

结论

Angular 17 充满了令人期待的新功能,是名副其实的“Angular 复兴”。 WebStorm 2023.3 引入了针对这些新 API 的支持,并且该版本包括许多实用的快速修复以及增强的严格模板检查。 我们将在后续版本中进一步改进控制流支持。 敬请关注更多动态!

WebStorm 团队

本博文英文原作者:

image description