你知道吗?Angular 9 就要来啦!Angular 是基于 TypeScript 的 Web 应用程序框架,Angular 9 的一系列更新将为开发者们带来不小的影响。本文将主要从最新功能、重大更改、Angular 组件等方面对 Angular 9 的相关动态进行详解。
Angular 9 RC 版已经发布了,这对 Angular 开发人员来说真是激动人心的时刻——我针对的不是 Angular 9 RC 的发布,我说的是 Ivy,Ivy 现在是 Angular 中的默认渲染引擎。
相信我,如果你还没觉得有多兴奋,请看看Mathias Raacke的推文:一个Hello World应用才有7KB大小!
下面我们就来研究一下,看看除了Ivy还有哪些东西。
新功能
添加对未装饰类的迁移支持
对指令和组件来说,直到Angular 8时装饰器对基类都是可选的。这适用于未使用@Injectable装饰器的服务。
export class BasePlain {
constructor(private vcr: ViewContainerRef) {}
}
@Directive({selector: '[blah]'})
export class DerivedDir extends BasePlain {}
引擎变成Ivy后这种类也需要装饰器。为了处理这种情况,使用ng update迁移时装饰器将作为迁移的一部分添加进来。请阅读此处内容以获取详情,有少数情况是不会被照顾到的。
FormControlName接受Number作为输入
下面的代码你可能已经用过很多次了,但是我们从来没有考虑过[formControlName]=“i”的工作机制;因为它接受字符串类型的值,所以没有fullTemplateTypeCheck也可以。但是在Ivy中这样做会失败。为了确保下面的语法仍然有效,formControlName可以接受string | number类型的值。
<div formArrayName="tags">
<div *ngFor="let tag of tagsArray.controls; index as i">
<input [formControlName]="i">
</div>
</div>
用TestBed.inject替换TestBed.get
在Angular 8中有一项重大更改,TestBed.get不再接受字符串值;现在团队决定回滚更改,因为它影响到了更大的应用程序基础部分。现在我们有了类型安全的版本TestBed.inject,TestBed.get已弃用。
TestBed.get(ChangeDetectorRef) // returns any
TestBed.inject(ChangeDetectorRef) // returns ChangeDetectorRef
ViewChild中Static标志的默认值
Angular 8中引入的另一项重大更改,是ViewChild需要static标志。静态属性仍然存在,但使用假值时我们不再需要传递这个属性。使用ng update更新到Angular 9后,迁移会移除所有位置使用的{ static: false }。
@ViewChild(ChildDirective) child: ChildDirective;
@ViewChild(ChildDirective, { static: false }) child: ChildDirective; // similar to above code
ng-add支持@angular/localize
要使用@angular/localize,我们现在可以运行ng add @angular/localize,这条命令会安装软件包并将必要的导入添加到polyfills中,这也是它工作时需要的。
针对Template的FullTemplateTypeCheck
在使用Angular时常常会遇到一个问题:“为什么不严格检查模板的类型”。这是之前的情况,但是现在对于*ngIf、*ngFor这样的指令,甚至是管道都会是严格的。有3种模式可用于检查模板的类型:
- 基本模式:设置fullTemplateTypeCheck: false来启用;
- 完全模式:设置fullTemplateTypeCheck: true来启用;
- 严格模式:设置fullTemplateTypeCheck: true和strictTemplates: true来启用。
更多详情请参阅这篇文档。
TypeScript 3.6支持
新版Angular现在需要Typescript 3.6版本。下面是Lars Gyrup Brink Nielsen总结的Angular版本和对应的TypeScript版本支持。
Angular CLI、Anuglar、Node.js和TypeScript兼容性列表。
对ModuleWithProviders的泛型支持
如果你是Angular库的所有者,那么你很可能已经用过Angular 9中的ModuleWithProviders了。现在必须使用泛型ModuleWithProviders
新版已经添加了迁移原理图(Schematic),因此ng update将负责这部分的迁移。
之前的代码:
@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 }]
};
}
}
将原理图应用于库
ng update负责所有代码的迁移,但不适用于Angular库。在Angular 9中,ng update会将所有迁移原理图也应用于库项目。这对Angular库的作者来说是很重要的,可以让你的代码与最新更改保持同步。
不再需要entryComponents
如果你使用过Angular中的popup,则必须使用这个属性。有了它,你才能在动态加载组件后无需在模板中引用它。现在改用Ivy后就用不着它了。
重大更改
移除tslib依赖项
Angular现在不再依赖tslib。在早期版本的Angular中它是必需的,并且是依赖项的一部分。如果你不用Angular CLI,则可能需要安装这个包。
Forms
- ngForm:以前
</ ngForm>是有效的选择器,现在需要改用 </ ng-form>。 - NgFormSelectorWarning:在Angular 6中已弃用,现在已移除。此指令的目的是在使用已弃用的ngForm选择器时显示警告。
- FormsModule.withConfig:FormsModule.withConfig已被移除。我们需要直接使用FormsModule,之前withConfig用于接受以下选项:
opts: { warnOnDeprecatedNgFormSelector?: "never" | "once" | "always"; }
- 弃用类型RenderComponentType已被移除。请改用RendererType2。
- 弃用类型RootRenderer已被移除。请改用RendererFactory2。
Angular Translation
- Translations(通过loadTranslations()函数加载)现在必须使用MessageId作为Translation键,替代之前的SourceMessage字符串。
- 要将$localize函数附加到全局范围,请从@angular/localize/init导入。以前这里是@angular/localize。
- 要访问loadTranslations()和clearTranslations()函数,请从@angular/localize导入。以前这里是@angular/localize/run_time。
Service Worker
在ngsw-config.json中移除了versionedFiles属性
之前:
"assetGroups": [
{
"name": "test",
"resources": {
"versionedFiles": [
"/**/*.txt"
]
}
}
]
之后:
"assetGroups": [
{
"name": "test",
"resources": {
"files": [
"/**/*.txt"
]
}
}
]
Angular Bazel
- @angular/bazel ng_setup_workspace()已经用不着了,并且已被移除。Angular会假设你将在WORKSPACE文件中获取rules_nodejs,并且这里没有其他依赖项。只需移除对此函数的任何调用和对应的load语句。
- 如果你从@angular/bazel使用protractor_web_test_suite,现在要切换到@bazel/protractor包上。
弃用
- TestBed.get函数已弃用,建议使用类型安全的TestBed.inject。
完整指南请参阅官方文档。本文没有涉及Ivy的介绍内容,因为这是一个非常大的主题,我们将很快写一篇博文来介绍Ivy的所有功能。
Angular CLI
支持验证CLI版本
新增检查可以验证所安装的CLI是否为最新发布的版本。如果不是最新版,那么在运行ng update时将安装最新版本,作为临时包来运行迁移。
支持混合多种配置
之前我们使用ng build时可以使用–configuration来传递配置,一个问题是,如果我想覆盖某些配置,我们必须复制整个配置并创建一个新条目才能使用它。
现在可以使用ng build --configuration=prod,testing这样的写法,这样在testing配置中我们就可以只传递需要覆盖的配置。
指定ng-add的选项
另一项更新针对Angular库的作者,你可以使用ng add来指定是否应将包添加到依赖项。
你可以在package.json中指定以下选项:
ng-add : {
"save": false | true | 'dependencies' | 'devDependencies'
}
组件原理图的类型选项
目前来说,当我们使用ng gc user时,它将使用组件类UserComponent生成一个文件,其类型选项可让你定义要创建的组件类型;例如ng gc user --type=“dialog”将创建一个组件,其类名称为UserDialog。
生成拦截器的原理图支持
目前来说添加拦截器都是手动的。在Angular 9中,我们将能够使用ng g i custom创建CustomInterceptor类。
app-shell原理图更改
为了生成app-shell,我们必须传递–clientProject;它现在是可选的。如果没有提供,它将考虑默认项目。
生成原理图时跳过测试
如果我们使用–minimal=true创建应用程序,它将跳过端到端和单元测试配置。但当我们使用ng g生成component/pipe/service时,它会添加一个spec.ts文件。从Angular CLI 9开始这个问题已经解决了。
自动发现multiSelect schema prompt
现在要创建一个可以有multiSelect的prompt,我们必须提供其他许多选项。在Angular 9中,可以像下面的配置一样简化这里的步骤。
test: {
type: 'array',
'x-prompt': {
'type': 'list',
'multiselect': false,
'items': [
{
'value': 'one',
'label': 'one'
},
{
'value': 'two',
'label': 'two'
},
],
'message': 'test-message',
},
}
支持提供npmrc文件路径
npm中提供了NPM_CONFIG_USERCONFIG和NPM_CONFIG_GLOBALCONFIG变量。当提供这些变量时,Angular CLI会首选它们而非全局.npmrc文件。请参阅npm文档以获取更多细节。
重大更改
- 使用CLI时会移除styleext和spec选项,而应使用style和skipTests选项替代。
Angular组件
新的Clipboard模块
有一个新的剪贴板组件可用,它是@angular/cdk系列的一部分。
想要了解更多实现细节,请阅读Tim Deschryver的博客文章。
hammerjs现在是可选的
在早期版本中需要hammerjs来添加手势支持。它现在是可选的,并且内部使用的所有实现都已移除,你可以使用@angular/platform-browser中的HammerModule。
针对谷歌地图的新包
@angular/google-maps包现已发布,所以集成谷歌地图不再是一项艰巨的任务了。这个包已经在多种设备上进行了测试。你可以参考Tim Deschryver的博客文章了解实现细节。
重大更改
- 组件不再可以通过@angular/material导入。现在要使用单独的辅助入口点,例如@angular/material/button。
- MAT_CHECKBOX_CLICK_ACTION已弃用,请使用MAT_CHECKBOX_DEFAULT_OPTIONS代替。
总结
终于看到Ivy更加稳定并且可以用于生产了,我感到非常兴奋,相信你也很会很激动。Angular CLI新增了许多很棒的功能,提升了我们的工作效率。很高兴看到Angular Material中添加了一些很棒的组件,例如地图和剪贴板。相信我,现在有了Ivy,我们可以对未来抱有更大的期待,因此Angular无疑会迎来激动人心的时刻,你也应该为此感到振奋。
作者介绍:
Santosh Yadav拥有10多年的经验,他是Angular和NgRx的开源贡献者,并且是AngularInDepth和DotNetTricks的作者。
原文链接:
https://blog.angularindepth.com/exciting-time-ahead-be-ready-for-angular-9-b3dbb4078c47