Angular 8/9升级至Angular 10指南

随着Angular框架的不断发展,为了利用最新的功能和性能改进,升级到最新版本是每个开发者都需要面对的任务。本文将指导如何将Angular 8或9项目升级到Angular 10。

升级前的准备工作

在开始升级到Angular 10之前,首先需要确保项目已经更新到Angular 9的最新补丁版本。此外,还需要对代码进行一些必要的修改,以确保兼容性。

更新Angular 9项目到Angular 10

如果已经有一个Angular 9项目,并且希望升级到Angular 10,那么以下是需要遵循的步骤:

在将项目升级到Angular 10之前,请确保首先更新到Angular 9的最新稳定版本。在终端中运行以下命令:

$ ng update @angular/core@9 @angular/cli@9

确保添加了Angular 9的版本号,以安装这个版本的最新补丁,否则可能会安装Angular 10。

如果已经将项目更新到Angular 9版本,只需要做几件事情:

  • 需要将代码迁移到使用TestBed.inject<T>方法,而不是TestBed.get()方法。
  • 需要从模块的@NgModule()装饰器中移除entryComponents属性,因为它们不再需要。

如果已经对代码进行了必要的修改,并且将Angular项目更新到了Angular 9的最新补丁版本,那么可以使用ng update命令将其更新到Angular 10。返回到终端并运行以下命令:

$ ng update @angular/cli @angular/core

注意:由于Angular 10不是当前的最终版本,需要使用--next标志,如下所示:

$ ng update @angular/cli @angular/core --next

代码修改指南

在升级过程中,可能需要对代码进行一些修改以确保兼容性。以下是一些常见的修改点:

如果在模板中使用了Angular表单的<ngForm>指令,需要将任何<ngForm>实例更新为<ng-form>。例如,如果声明了一个如下的表单:

<ngForm #exampleForm="ngForm"> <input [(ngModel)]="userName" name="userName" /> </ngForm>

只需要按照以下方式更新:

<ng-form #exampleForm="ngForm"> <input [(ngModel)]="userName" name="userName" /> </ng-form>

使用的@ContentChild@ContentChildren装饰器将不再能够匹配它们自己的宿主节点。

在Angular 9之前,可以这样使用@ContentChild内容查询来访问指令的宿主ElementRef

@Directive({ selector: '[myActions]' }) export class MyDirective implements AfterContentInit { @ContentChild(MyDirective, {static: true, read: ElementRef}) selfElementRef: ElementRef; constructor(private readonly renderer: Renderer2) {} ngAfterContentInit() { const el = this.selfElementRef.nativeElement as HTMLElement; if (!el) { return; } this.renderer.setStyle(el, 'color', 'black'); } }

需要将之前的代码更改为通过注入依赖来访问ElementRef

@Directive({ selector: '[myActions]' }) export class MyDirective implements AfterContentInit { constructor(private readonly elementRef: ElementRef, private readonly renderer: Renderer2) {} ngAfterContentInit() { const el = this.elementRef.nativeElement as HTMLElement; if (!el) { return; } this.renderer.setStyle(el, 'color', 'black'); } }

这样,就不需要使用@ContentChild()@ContentChildren()装饰器来查询宿主元素了。

由于Angular 9+默认使用的Ivy渲染器,模板具有类型检查。在Angular 9版本之前,模板变量具有TypeScript的any类型,即可以更改对象并使用未知属性,编译器不会报错。

从使用Ivy渲染器的Angular 9版本开始,模板变量将根据TypeScript编译器选项对模板类型检查的严格程度进行强类型化。因此,需要避免直接在模板中更改模板变量。

让看一个会改变模板变量的例子:

<button #myBtn (click)="myBtn.state = 'clicked'"> Click Me </button>

在Angular 8版本中,myBtn模板变量具有any类型。从Angular 9版本开始,模板变量将具有内置的HTMLButtonElement类型。因此,将会遇到错误,因为HTMLButtonElement接口没有state成员。

要修复这个问题,需要重构任何对模板变量的更改,并用组件方法替换它们。例如:

<button (click)="onClick()"> Click Me </button>

简单地移除了模板变量,并在组件的类中添加了onClick()方法和state属性:

export class MyComponent { state = 'not clicked'; onClick(): void { this.state = 'clicked'; } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485