阅读(1192) (0)

Angular 弃用清单

2022-07-12 17:50:31 更新

已弃用的 API 和特性

Angular 力图兼顾创新与稳定。但有时,API 和特性已经过时,需要进行删除或替换,以便 Angular 可以及时跟上新的最佳实践、依赖项变更或者 Web 平台自身的变化。

为了使这些转换尽可能容易,我们在删除这些 API 和特性之前会弃用它们一段时间。这让你有时间将应用程序更新为最新的 API 和最佳实践。

本指南包含了当前已弃用的所有 Angular API 和特性的汇总表。

索引

为帮助你的项目面向未来,下表列出了所有已弃用的 API 和特性,并按它们将被移除的候选版本进行组织。每个项目都链接到本指南后面描述弃用原因和替换选项的部分。

特性区

API 或特性

将移除于

@angular/common ReflectiveInjector v11
@angular/common CurrencyPipe ​- ​DEFAULT_CURRENCY_CODE v11
@angular/common/http XhrFactory v15
@angular/common/http/testing

TestRequest 接受 ErrorEvent 参数以进行错误模拟

v16
@angular/core DefaultIterableDiffer v11
@angular/core ReflectiveKey v11
@angular/core RenderComponentType v11
@angular/core

ApplicationRef.bootstrap​ 的基于工厂的签名

v15
@angular/core PlatformRef.bootstrapModuleFactory v15
@angular/core getModuleFactory v16
@angular/core ModuleWithComponentFactories v16
@angular/core Compiler v16
@angular/core CompilerFactory v16
@angular/core NgModuleFactory v16
@angular/platform-browser-dynamic JitCompilerFactory v16
@angular/forms

和响应式表单一起使用 ​ngModel

v11
@angular/upgrade @angular/upgrade v11
@angular/upgrade getAngularLib v11
@angular/upgrade setAngularLib v11
@angular/upgrade

downgradeModule ​基于工厂的签名

v15

模板语法

<template> v11

腻子脚本

reflect-metadata v11
@angular/compiler-cli

@Input setter​ 强制类型转换

v15
@angular/compiler-cli fullTemplateTypeCheck v15
@angular/core defineInjectable v11
@angular/core entryComponents v11
@angular/core ANALYZE_FOR_ENTRY_COMPONENTS v11
@angular/core

ViewContainerRef.createComponent​ 基于工厂的签名

v15
@angular/core/testing TestBed.get v12
@angular/core/testing async v12
@angular/core/testing

aotSummaries ​中的 ​TestBed.initTestEnvironment​ 参数

v14
@angular/core/testing

TestModuleMetadata ​类型的 ​aotSummaries ​字段

v14
@angular/forms

FormBuilder.group​ 老式选项参数

v14
@angular/platform-server renderModuleFactory v15
@angular/service-worker SwUpdate#activated v16
@angular/service-worker SwUpdate#available v16

模板语法

/deep/​, ​>>>​ 和 ​::ng-deep

未指定

模板语法

bind-​, ​on-​, ​bindon-​ 和 ​ref-

v15

要了解 Angular CDK 和 Angular Material 的弃用情况,参阅变更记录

已弃用的 API

本节包含所有当前已弃用的 API 的完整列表,其中包含一些可帮助你规划如何迁移到其替代品的详细信息。

@angular/common

API

替代品

声明弃用于

备注

CurrencyPipe ​- ​DEFAULT_CURRENCY_CODE {provide: DEFAULT_CURRENCY_CODE, useValue: 'USD'} v9

从 v11 开始,默认代码将从 LOCALE_ID 给出的语言环境数据中提取,而不是 USD 。

@angular/common/http

API

替代品

声明弃用于

备注

XhrFactory

@angular/common 中的 XhrFactory

v12

XhrFactory 已从 @angular/common/http 移到了 @angular/common 。

@angular/core

API

替代品

声明弃用于

备注

DefaultIterableDiffer n/a v4

不再是公共 API。

ReflectiveInjector Injector.create() v5

参见下文的 ​ReflectiveInjector

ReflectiveKey

v5

defineInjectable ɵɵdefineInjectable v8

仅在生成的代码中使用。任何源代码都不应依赖此 API。

entryComponents

v9

参见下文的 ​entryComponents

ANALYZE_FOR_ENTRY_COMPONENTS

v9

参见下文的 ​ANALYZE_FOR_ENTRY_COMPONENTS

async waitForAsync v11

来自 @angular/core/testing 的​async​函数已重命名为 waitForAsync 以避免与原生 JavaScript async 语法混淆。现有特性已弃用,将在未来版本中删除。

getModuleFactory getNgModuleById v13

Ivy 允许直接使用 NgModule 类,而无需检索相应的工厂。

ViewChildren.emitDistinctChangesOnly / ContentChildren.emitDistinctChangesOnly

无(是问题 #40091的一部分)

这是作为问题 #40091的错误修复的一部分引入的临时标志,将被删除。

ApplicationRef.bootstrap​的基于工厂的签名

ApplicationRef.bootstrap​的基于类型的签名

v13

有了 ivy,不需要解析 Component factory,直接提供 Component Type 即可。

PlatformRef.bootstrapModuleFactory PlatformRef.bootstrapModule v13

有了 ivy,就不需要解析 NgModule factory,直接提供 NgModule Type 即可。

ModuleWithComponentFactories

v13

Ivy JIT 模式不需要访问这个符号。

Compiler

v13

Ivy JIT 模式不需要访问这个符号。

CompilerFactory

v13

Ivy JIT 模式不需要访问这个符号。

NgModuleFactory

使用基于非工厂的框架 API,如PlatformRef.bootstrapModule​和​createNgModuleRef

v13

Ivy JIT 模式不需要访问这个符号。

ViewContainerRef.createComponent​ 基于工厂的签名

ViewContainerRef.createComponent​ 基于类型的签名

v13

Angular 不再需要组件工厂来动态创建组件。使用 createComponent 方法的不同签名,允许直接传递 Component 类。

@angular/core/testing

API

替代品

声明弃用于

备注

TestBed.get TestBed.inject v9

行为没变,但类型安全。

async waitForAsync v10

行为相同,只是改名以免混淆。

aotSummaries ​中的 ​TestBed.initTestEnvironment​ 参数

无需更换

v13

Ivy 中不使用摘要文件。

TestModuleMetadata ​类型的 ​aotSummaries ​字段

无需更换

v13

Ivy 中未使用摘要文件。

@angular/platform-browser-dynamic

API

替代品

声明弃用于

备注

JitCompilerFactory

v13

不再需要此符号。

@angular/platform-server

API

替代品

声明弃用于

备注

renderModuleFactory renderModule v13

不再需要此符号。

@angular/forms

API

替代品

声明弃用于

备注

ngModel ​与响应式表单一起使用

FormControlDirective v6

FormBuilder.group​ 老式选项参数

AbstractControlOptions ​参数值

v11

@angular/service-worker

API

替代品

声明弃用于

备注

SwUpdate#activated

SwUpdate#activateUpdate()​ 的返回值

v13

SwUpdate#activateUpdate() 的返回值指示更新是否成功激活。

SwUpdate#available SwUpdate#versionUpdates v13

SwUpdate#available 的行为可以通过过滤​SwUpdate#versionUpdates​上的 VersionReadyEvent 事件来重建

@angular/upgrade

API

替代品

声明弃用于

备注

所有入口点

@angular/upgrade/static v5

参阅从 AngularJS 升级

@angular/upgrade/static

API

替代品

声明弃用于

备注

getAngularLib getAngularJSGlobal v5

参阅从 AngularJS 升级

setAngularLib setAngularJSGlobal v5

参阅从 AngularJS 升级

downgradeModule ​基于工厂的签名

downgradeModule ​基于 NgModule 的签名

v13

downgradeModule 支持更符合人体工程学的基于 NgModule 的 API(相对于基于 NgModule 工厂的 API)。

已弃用的特性

本部分列出了所有当前已弃用的特性,其中包括模板语法、配置选项以及上述已弃用 API部分中未列出的任何其他弃用特性。它还包括已弃用的 API 使用场景或 API 组合,以作为上述信息的补充。

Bazel 构建器和原理图

Angular Labs 中引入了 Bazel 构建器和原理图,让用户无需管理 Bazel 版本和 BUILD 文件即可试用 Bazel。此特性已被弃用。

Web 跟踪框架集成

Angular 以前支持与Web 跟踪框架 (WTF)集成,以对 Angular 应用程序进行性能测试。此集成未经维护,现已失效。因此,该集成在 Angular 版本 8 中被弃用,并且由于没有任何现有使用的证据,因此在版本 9 中被删除。

/deep/ 、 >>> 和 ::ng-deep 组件样式选择器

这类 shadow-dom-piercing 后代组合器已弃用,并且正在从主要浏览器和工具中删除支持。因此,在 v4 中,我们弃用了 Angular 对 ​/deep/​ 、 ​>>>​ 和 ​::ng-deep​ 三个的支持。在正式移除之前, ​::ng-deep​ 是首选,因为它与工具具有更广泛的兼容性。

bind- 、 on- 、 bindon- 和 ref- 前缀

模板前缀 ​bind-​ 、 ​on-​ 、 ​bindon-​ 和 ​ref-​ 在 v13 中已被弃用。模板应该使用更广为人知的语法进行绑定和引用:

  • [input]="value"​ 代替 ​bind-input="value"
  • [@trigger]="value"​ 代替 ​bind-animate-trigger="value"
  • (click)="onClick()"​ 代替 ​on-click="onClick()"
  • [(ngModel)]="value"​ 代替 ​bindon-ngModel="value"
  • #templateRef​ 代替 ​ref-templateRef

<template> 标签

<template>​ 标签在 v4 中已被弃用,以避免与 DOM 的同名元素发生冲突(例如在使用 Web 组件时)。使用 ​<ng-template>​ 代替。

和响应式表单一起使用 ngModel

在 Angular v6 中已不推荐把 ​ngModel ​输入属性、​ngModelChange ​事件与响应式表单指令一起使用,并将在 Angular 的未来版本中删除。

现在已经弃用:

<input [formControl]="control" [(ngModel)]="value">
this.value = 'some value';

出于多种原因,此支持已被弃用。首先,开发人员发现这种模式令人困惑。似乎正在使用实际的 ​ngModel ​指令,但实际上它是响应式表单指令上名为 ​ngModel ​的输入/输出属性,它模拟了该指令的一些行为,但又不完全一样。它允许获取和设置值并拦截值事件,但 ​ngModel ​的一些其他特性,例如使用 ​ngModelOptions ​延迟更新或导出指令,不起作用。

另外,该模式混用了模板驱动和响应式这两种表单策略,这会妨碍我们获取任何一种策略的全部优点。 在模板中设置值的方式,也违反了响应式表单所遵循的“模板无关”原则;反之,在类中添加 ​FormControl​/​FormGroup ​层也破坏了“在模板中定义表单”的约定。

要在移除支持之前更新你的代码。你需要决定是坚持使用响应式表单指令(并使用响应式表单模式来获取/设置值)还是切换到模板驱动表单指令。

之后(选择 1 - 使用响应式表单):

<input [formControl]="control">
this.control.setValue('some value');

之后(选择 2 - 使用模板驱动表单):

<input [(ngModel)]="value">
this.value = 'some value';

默认情况下,当你使用此模式时,你将在开发模式下看到一次弃用警告。你可以通过在导入时配置 ​ReactiveFormsModule ​来选择消除此警告:

imports: [
  ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'})
],

或者,你可以选择为该模式的每个实例显示一个单独的警告,配置值为 ​"always"​ 。这可能有助于在更新代码时跟踪代码中使用模式的位置。

ReflectiveInjector

在 v5 中,Angular 用 ​StaticInjector ​代替了 ​ReflectiveInjector​。该注入器不再需要 Reflect 的腻子脚本,对大部分开发人员来说都显著减小了应用的体积。

之前:

ReflectiveInjector.resolveAndCreate(providers);

之后:

Injector.create({providers});

loadChildren 字符串语法

当 Angular 第一次引入惰性路由时,还没有浏览器能支持动态加载额外的 JavaScript。因此 Angular 创建了自己的方案,所用的语法是 ​loadChildren: './lazy/lazy.module#LazyModule'​ 并且还构建了一些工具来支持它。现在,很多浏览器都已支持 ECMAScript 的动态导入,Angular 也正朝着这个新语法前进。

在版本 8 中,不推荐使用 ​loadChildren ​路由规范的字符串语法,而是改用基于 ​import()​ 的新语法。

之前:

const routes: Routes = [{
    path: 'lazy',
    // The following string syntax for loadChildren is deprecated
    loadChildren: './lazy/lazy.module#LazyModule',
  }];

之后:

const routes: Routes = [{
    path: 'lazy',
    // The new import() syntax
    loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
  }];

版本 8 更新:当你更新到版本 8 时, ​ng update​ 命令会自动执行转换。在版本 7 之前, ​import()​ 语法仅适用于 JIT 模式(使用视图引擎)。

声明语法:遵循路由声明语法 ​loadChildren: () => import('...').then(m => m.ModuleName)​ 很重要,这样 ​ngc ​才能发现惰性加载的模块和关联的 ​NgModule ​。你可以在此处找到允许的语法结构的完整列表。这些限制将随着 Ivy 的发布而放宽,因为它将不再使用 ​NgFactories ​。

JIT 模式下对反射元数据 polyfill 的依赖

Angular 应用程序,特别是依赖于 JIT 编译器的应用程序,过去常常需要 reflect-metadata API 的腻子脚本。

在 Angular 8.0 版(见#14473 )中移除了对这个腻子脚本的需求,这将使得大多数 Angular 应用程序不再需要此腻子脚本。因为此腻子脚本可能被第三方库依赖,因此不能从所有 Angular 项目中删除它,我们从 8.0 版本开始弃用对这个腻子脚本的要求。这样可以给库作者和应用程序开发人员足够的时间来评估他们是否需要此腻子脚本,并执行任何必要的重构以消除对它的依赖。

在典型的 Angular 项目中,这个腻子脚本不用于生产版本,因此删除它不会影响生产环境的应用程序。删除它是为了从整体上上简化构建设置并减少外部依赖项的数量。

@ViewChild() / @ContentChild() 默认使用静态解析

在版本 9 中,​@ViewChild​ 和 ​@ContentChild​ 这两个查询的默认设置会改变,以修复查询中的 BUG 和意外行为。

为了应对这个变化,我们从版本 8 开始就要开始迁移所有应用和库,显式指定 ​@ViewChild​ 和 ​@ContentChild​ 查询的解析策略。

具体来说,这次迁移会添加一个显式的 “static” 标志,用来指出应该何时对该查询的结果进行赋值。等升级到版本 9 的时候,这个标志可以确保这些代码的工作方式都是一样的。

之前:

// query results sometimes available in `ngOnInit`, sometimes in `ngAfterViewInit` (based on template)
@ViewChild('foo') foo: ElementRef;

之后:

// query results available in ngOnInit
@ViewChild('foo', {static: true}) foo: ElementRef;

OR

// query results available in ngAfterViewInit
@ViewChild('foo', {static: false}) foo: ElementRef;

从版本 9 开始,​static ​标志将默认为 ​false​。那时候,可以安全地删除所有 ​{static: false}​ 标志,而且我们还会提供一个能帮你更新代码的原理图(schematic)。

注意:这个标志只适用于 ​@ViewChild​ 和 ​@ContentChild​ 这两个查询,这是因为 ​@ViewChildren​ 和 ​@ContentChildren​ 查询都没有静态和动态的概念(它们总是“动态”解析)。

@ContentChild() / @Input() 一起使用

以下模式已弃用:

@Input() @ContentChild(TemplateRef) tpldeprecated !: TemplateRef<any>;

不要再使用此模式,而应该将这两个装饰器分离到它们各自的属性中并添加回退逻辑,如下例所示:

@Input() tpl !: TemplateRef<any>;
@ContentChild(TemplateRef) inlineTemplate !: TemplateRef<any>;

无法赋值给模板变量

在以下示例中,双向绑定意味着应在 ​valueChange ​事件触发时写入 ​optionName ​。

<option *ngFor="let optionName of options" [(value)]="optionName"></option>

然而,在实践中,Angular 忽略了对模板变量的双向绑定。从版本 8 开始,不推荐对模板变量赋值。在未来的版本中,我们将抛出错误以指出不支持写入。

<option *ngFor="let optionName of options" [value]="optionName"></option>

在 platform-server 中绑定到 innerText

在服务器端渲染中使用的 Domino 不支持 ​innerText​,因此在平台服务器中的 “domino 适配器”中,如果尝试绑定到 ​innerText​,则有一些特殊代码可以退回到 ​textContent​。

这两个属性有细微的差别,因此在幕后切换到 ​textContent ​可能会让用户感到惊讶。出于这个原因,我们弃用了这种行为。展望未来,用户应该在使用 Domino 时显式绑定到 ​textContent ​。

wtfStartTimeRange 和所有 wtf* API

所有 ​wtf*​ API 均已弃用,并将在未来版本中删除。

不再需要 entryComponents 和 ANALYZE_FOR_ENTRY_COMPONENTS

以前, ​NgModule ​定义中的 ​entryComponents ​数组用于告诉编译器将动态创建和插入哪些组件。使用 Ivy 后,这不再是必需的,并且可以从现有模块声明中删除 ​entryComponents ​数组。这同样适用于 ​ANALYZE_FOR_ENTRY_COMPONENTS ​注入令牌。

注意:如果构建将由 View Engine 应用程序使用的库,你可能仍需要保留它们。

不带泛型的 ModuleWithProviders 类型

一些 Angular 库,例如 ​@angular/router​ 和 ​@ngrx/store​ ,实现的 API 返回名为 ModuleWithProviders 的类型(通常使用名为 ​ModuleWithProviders ​​forRoot()​ 的方法)。这种类型代表一个 ​NgModule ​以及其他提供者。 Angular 版本 9 已弃用没有明确泛型类型的 ​NgModule ​​ModuleWithProviders ​类型。在 Angular 的未来版本中,泛型将不再是可选的。

如果你使用的是 CLI,则 ​ng update​ 应该会自动迁移代码。如果没有使用 CLI,则可以将任何缺失的泛型类型手动添加到应用程序中。例如:

之前

@NgModule({
/* ... */
})
export class MyModule {
  static forRoot(config: SomeConfig): ModuleWithProviders {
    return {
      ngModule: SomeModule,
      providers: [
        {provide: SomeConfig, useValue: config}
      ]
    };
  }
}

之后:

@NgModule({
/* ... */
})
export class MyModule {
  static forRoot(config: SomeConfig): ModuleWithProviders<SomeModule> {
    return {
      ngModule: SomeModule,
      providers: [
        {provide: SomeConfig, useValue: config}
      ]
    };
  }
}

输入 setter 强制类型转换

由于在 Angular 中引入了 ​strictTemplates ​标志,编译器已经能够根据相应指令的声明输入类型对输入绑定进行类型检查。当 “getter/setter 对”用于输入时,可能需要让 setter 接受比 getter 返回的类型更宽泛的类型集,例如当 setter 首次转换输入值时。然而,在 TypeScript 4.3 之前,需要 getter/setter 对具有相同的类型,因此无法准确地声明此模式。

为了减轻这种限制,可以在对输入绑定进行类型检查时用到的指令中声明输入 setter 强制类型转换字段。但是,从 TypeScript 4.3 开始,此限制已被移除; setter 现在可以接受比 getter 返回的类型更宽泛的类型。这意味着不再需要输入强制类型转换字段,因为它们的效果可以通过拓宽 setter 的类型来实现。

例如,以下指令:

@Component({
})
export class SubmitButtonComponent {
  static ngAcceptInputType_disabled: boolean|'';

  private disabledValue = false;

  @Input()
  get disabled(): boolean {
    return this.disabledValue;
  }
  set disabled(value: boolean) {
    this.disabledValue = (value === '') || value;
  }
}

可以重构如下:

@Component({
})
export class SubmitButtonComponent {
  private disabledValue = false;

  @Input()
  get disabled(): boolean {
    return this.disabledValue;
  }

  set disabled(value: boolean|'') {
    this.disabledValue = (value === '') || value;
  }
}

fullTemplateTypeCheck

使用 AOT 编译器编译你的应用程序时,你的模板会根据特定的严格级别进行类型检查。在 Angular 9 之前,​fullTemplateTypeCheck ​编译器选项只支持两个严格级别的模板类型检查。在版本 9 中引入了 ​strictTemplates ​系列编译器选项,作为一种更细粒度的方法来配置模板的类型检查的严格程度。

fullTemplateTypeCheck ​标志已被弃用,取代它的是新的 ​strictTemplates ​选项及其相关的编译器选项。当前已配置为 ​fullTemplateTypeCheck: true​ 的项目可以迁移到以下编译器选项集以实现相同级别的类型检查:

{
  "angularCompilerOptions": {
    ...
    "strictTemplates": true,
    "strictInputTypes": false,
    "strictNullInputTypes": false,
    "strictAttributeTypes": false,
    "strictOutputEventTypes": false,
    "strictDomEventTypes": false,
    "strictDomLocalRefTypes": false,
    "strictSafeNavigationTypes": false,
    "strictContextGenerics": false,
    ...
  }
}

由于 ViewEngine 弃用而导致的 JIT API 更改

在 ViewEngine 中, JIT 编译需要在应用程序中注入特殊的提供者(如 ​Compiler​、​CompilerFactory ​等)并调用相应的方法。使用 Ivy,如果 Component、NgModule 等尚未进行 AOT 编译 ,则 JIT 编译会隐式进行。这些特殊的提供者在 Ivy 中仍然可用,以便与 ViewEngine 向后兼容,从而使向 Ivy 的过渡更加顺畅。由于 ViewEngine 已被弃用并将很快被删除,因此这些符号现在也已被弃用。

重要说明:此弃用不会影响 Ivy 中的 JIT 模式(JIT 在 Ivy 中仍然可用,但是我们正在探索将来弃用它的可能性。请参阅 RFC:Angular JIT 编译模式的用例探索)。

TestRequest 接受 ErrorEvent 参数

Angular 提供了一些用于测试 ​HttpClient ​的实用工具。 ​@angular/common/http/testing​ 中的 ​TestRequest ​类会模拟 HTTP 请求对象以与 ​HttpTestingController​ 一起使用。

TestRequest ​提供了一个 API 来模拟带有错误的 HTTP 响应。在早期版本的 Angular 中,此 API 接受 ​ErrorEvent ​类型的对象,这与浏览器本机返回的错误事件类型不匹配。如果你要将 ​ErrorEvent ​与 ​TestRequest ​一起使用,就应该切换到 ​ProgressEvent ​。

这是使用 ​ProgressEvent ​的示例:

const mockError = new ProgressEvent('error');
const mockRequest = httpTestingController.expectOne(..);

mockRequest.error(mockError);

弃用的 CLI API 和选项

本节包含所有当前已弃用的 CLI 标志的完整列表。

@angular/cli

API/选项

可能移除于

备注

--prod v14

改用 --configuration production 。

ng update --all v14

已无效果。

@angular-devkit/build-angular

API/选项

可能移除于

备注

deployUrl v15

使用 baseHref 选项、 APP_BASE_HREF DI 令牌或两者的组合。

showCircularDependencies v14

在项目代码中检测循环依赖的推荐方法是使用 lint 规则或其他外部工具。

Protractor 构建器

v14

作为 Protractor 弃用的一部分而弃用。

@angular-devkit/build-optimizer

整个 NPM 包已弃用。它一直是实验性的(从未达到 ​1.0.0​ )并且一直是 Angular CLI 的内部包。所有相关特性都已移至 ​@angular-devkit/build-angular​ 。

删除的 API

从 11.0.0*开始,已经移除了以下 API:

API

替代品

@angular/router preserveQueryParams queryParamsHandling

[style] 和 [style.prop] 绑定的样式清理

Angular 会清理 ​[style]​ 和 ​[style.prop]​ 绑定,以防止恶意代码通过 CSS ​url()​ 条目中的 ​javascript:​ 表达式进行插入。但是,大多数现代浏览器都已不再支持这些表达式的使用,所以这种清理只对 IE 6 和 7 才有意义。鉴于 Angular 不支持 IE 6 或 7,并且这种清理有性能代价,因此我们将不再清理 Angular 版本 10 中的样式绑定。

@angular/router 中的 loadChildren 字符串语法

不能再用 ​loadChildren ​字符串语法来配置惰性路由。字符串语法已替换为动态导入语句。 ​DeprecatedLoadChildren ​类型已从 ​@angular/router​ 中删除。

支持类 ​NgModuleFactoryLoader ​、 ​SystemJsNgModuleLoader ​和 ​SystemJsNgModuleLoaderConfig ​类已从 ​@angular/core​ 中删除,并且 ​SpyNgModuleFactoryLoader ​已从 ​@angular/router​ 中删除。

WrappedValue

WrappedValue ​是为了供变更检测用的,它允许将相同的对象实例视为不同的。在 ​Observable ​产生相同值实例的情况下,它通常与 ​async ​管道一起使用。

鉴于此用例相对较少且特殊处理会影响应用程序性能, ​WrappedValue ​API 已在 Angular 13 中删除。

如果你依赖同一个对象实例应该引起更改检测的行为,你有两个选择:

  • 克隆结果值,使其具有新的标识。
  • 显式调用​ChangeDetectorRef.detectChanges()​已强制更新。