codecamp

Angular 升级到最新版

更新 Angular

本指南包含更新到 Angular 版本 13 的信息。

更新 Angular CLI 应用程序

有关如何更新到最新的 Angular 版本和利用 Angular 自动迁移工具的分步说明,请使用 update.angular.io 上的交互式更新指南。

版本 13 中的更改与弃用

  • 移除视图引擎
  • 需要使用 Ivy 构建所有应用程序和库。请参阅即将到来的 Angular 库分发改进 博客。

  • Angular 包格式 (APF) 的现代化
  • 移除了旧的输出格式,包括视图引擎特有的元数据。

  • 移除对 IE11 的支持
  • 移除对 Microsoft Internet Explorer 11 (IE11) 的所有支持。请参阅 问题 #41840

  • 测试平台模块清理
  • 在 ​initTestEnvironment ​中添加选项以从应用程序中完全移除测试环境。请参阅 通过启用 Angular 测试模块清理来改进 Angular 测试 文章。

  • $localize​ 标记的消息字符串
  • 添加 Angular ​$localize​ API 和标记消息字符串的文档。

  • 磁盘缓存
  • 默认情况下会为所有应用程序启用持久构建缓存。请参阅 问题 #21545

Angular 版本 13 中的重大变化

详情

PR #43642

PR #43642

不再支持 4.4.2 之前的 TypeScript 版本。

PR #43740

PR #43740

不再支持早于 v12.20.0 的 NodeJS 版本。 Angular 包现在使用带有子路径模式的 NodeJS 包导出功能,并且需要高于 14.15.0 或 16.10.0 的 NodeJS 版本。

PR #31187

PR #31187

以前,默认的 url 序列化程序移除了查询参数中包含问号之后的所有内容。也就是说,如果要导航到 /path?q=hello?&other=123,查询参数解析为仅 {q: 'hello'}。这是不正确的,因为 URI 规范允许在查询数据中使用问号字符。此更改现在会正确地将 /path?q=hello?&other=123 的查询参数解析为 {v: 'hello?', other: '123'}

PR #41730

PR #41730

SpyLocation 使用的 RouterTestingModule 的行为已更改以匹配浏览器的行为。当 Location.go 被调用时,它不再发出 popstate 事件。此外, simulateHashChange 现在会同时触发 hashchange 事件和 popstate 事件。那些用到了 location.go 并期望 Router 获取更改的测试应迁移到 simulateHashChange。每个测试尝试断言的内容都不同,因此没有任何一种改法能适用于所有测试。每个使用 SpyLocation 来模拟浏览器 URL 更改的测试都应根据具体情况进行评估。

PR #42952

PR #42952

引入了一种称为 FormControlStatus 的新类型,它是表单控件所有可能状态字符串的联合。 AbstractControl.status 已经从 string 收窄到 FormControlStatus , statusChanges 已经从 Observable<any> 收窄到 Observable<FormControlStatus> 。大多数应用程序应该都能无缝地使用新类型。此更改导致的任何损坏都可能是由于以下两个问题之一造成的:
1. 该应用程序正在将 AbstractControl.status 与无效的状态字符串进行比较。
2. 该应用程序正在使用 statusChanges 事件,而它们不是字符串。

PR #43087

PR #43087

以前, routerLink 的 null 和 undefined 输入等效于空字符串,并且无法禁用链接的导航。此外,href 从 HostBinding() Property 绑定更改为 Attribute 绑定( HostBinding('attr.href') )。此更改的效果是 DebugElement.properties['href'] 现在会返回由原生元素返回的 href 值,该值是完整的 URL,而不是 RouterLink href 属性的内部值。

PR #43496

PR #43496

当新导航取消了正在进行的导航时,路由器不再替换浏览器 URL。浏览器 URL 的替换经常导致 URL 闪烁,这只是为了支持一些 AngularJS 混合应用程序。依赖于 Angular 路由器处理的每个初始导航上存在 navigationId 的混合应用程序应改为订阅 NavigationCancel 事件并手动执行 location.replaceState 以将 navigationId 添加到路由器状态中。此外,应调整在 SpyLocation 上断言 urlChanges 的测试以解决缺少 replaceState 触发器的问题。

PR #43507

PR #43507

WrappedValue 类不再从 @angular/core 导入。如果使用依赖 WrappedValue 的过时库,则此更改可能会导致编译错误或运行时失败。由于没有可用的替代品,因此应移除对 WrappedValue 的依赖。

PR #43591

PR #43591

不能再将 Route.loadChildren 与字符串值一起使用。从 @angular/core 中移除了以下支持类:
NgModuleFactoryLoader
SystemJsNgModuleFactoryLoader
@angular/router 包不再导出下列符号:
SpyNgModuleFactoryLoader
DeprecatedLoadChildren
来自 @angular/core/testing 的 setupTestingRouter 函数的签名已更改,移除了 NgModuleFactoryLoader 参数,因为无法创建该参数的值。

PR #43668

PR #43668

SwUpdate#activateUpdate 和 SwUpdate#checkForUpdate 的返回类型更改为 Promise<boolean> 。
尽管不太可能,但在某些情况下,此更改可能会导致 TypeScript 类型检查失败。如有必要,请更新你的类型以说明新的返回类型。

问题 #22159

通过动态 import() 加载的脚本现在被视为 ES 模块(意味着它们必须是严格模式兼容的)。

新的弃用

已移除

替代品

详情

getModuleFactory getNgModuleById
getModuleFactory getNgModuleById

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

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

使用基于类型的签名代替基于工厂的签名。

PlatformRef.bootstrapModuleFactory PlatformRef.bootstrapModule
ModuleWithComponentFactories

Compiler

CompilerFactory

NgModuleFactory

非基于工厂的框架 API

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

ViewContainerRef.createComponent​ 的基于工厂的签名

ViewContainerRef.createComponent​ 基于类型的签名

使用基于类型的签名代替基于工厂的签名。

TestBed.initTestEnvironment​ 方法 的 aotSummaries 参数

TestModuleMetadata​ 类型 的 aotSummaries 参数

renderModuleFactory renderModule

SwUpdate#activated

SwUpdate#activated

SwUpdate#activateUpdate()

SwUpdate#activateUpdate()

使用 ​SwUpdate#activateUpdate()​ 的返回值。

SwUpdate#available SwUpdate#versionUpdates
bind-input="value" [input]="value"
bind-animate-trigger="value" [@trigger]="value"
on-click="onClick()" (click)="onClick()"
bindon-ngModel="value" [(ngModel)]="value"
ref-templateRef #templateRef


Angular 浏览器支持
Angular 弃用清单
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

Angular 开发指南

Angular 特性预览

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }