学习如何成功更新到Angular版本9。
先决条件
在你开始用新的Ivy渲染器更新到Angular第9版之前,有几个先决条件你需要完成:
NgForm
选择器。
@ContentChild
和@contentchildren.
主机。
- 不要将值分配给仅模板的变量。
- TypeScript编译器更新(可选)。
渲染器
弃用。
让我们逐个分析一下。
NgForm
选择器
首先,更新所有NgForm
选择器在应用程序中使用
自定义元素。如果您正在使用标准,这不会影响您< >形式
元素或反应形式。
之前:
<NGForm.#personform.=”NGForm.”><mat-form-field><mat-label>搜索mat-label><输入matInput[(ngmodel)]=”问”的名字=”问”/>mat-form-field>NGForm.>
为了兼容,您需要从
来
:
<ng-form#personform.=”NGForm.”><mat-form-field><mat-label>搜索mat-label><输入matInput[(ngmodel)]=”问”的名字=”问”/>mat-form-field>ng-form>
@ContentChild
和@contentchildren.
主持人
的@ContentChild
和@contentchildren.
装饰器查询将不再能够匹配它们指令自己的主机节点。
之前:
@指令({选择器:'[Swractions]'})出口类ActionsDirective实现了后intentinit.{@ContentChild.(ActionsDirective,{静态:真正,读:Elementref.})自我refref.:Elementref.;构造函数(私人只读的渲染器:Renderer2){}ngAfterContentInit(){常量埃尔=这。自我refref.。母语作为htmlelement.;如果(!埃尔){返回;}这。渲染器。setstyle.(埃尔,'显示','柔性');这。渲染器。setstyle.(埃尔,'flexdirection',“行”);这。渲染器。setstyle.(埃尔,'justifycontent',“flex-end”);}}
以上,我们正在使用@ContentChild
内容查询访问主机Elementref.
对于指令。FWIW,这不是最好的做法,这就是为什么这是不推荐的。
理想情况下,我们正在访问Elementref.
通过注入我们的指令的依赖性:
@指令({选择器:'[Swractions]'})出口类ActionsDirective实现了后intentinit.{构造函数(私人只读的Elementref.:Elementref.,私人只读的渲染器:Renderer2){}ngAfterContentInit(){常量埃尔=这。Elementref.。母语作为htmlelement.;如果(!埃尔){返回;}这。渲染器。setstyle.(埃尔,'显示','柔性');这。渲染器。setstyle.(埃尔,'flexdirection',“行”);这。渲染器。setstyle.(埃尔,'justifycontent',“flex-end”);}}
这里的目标是避免使用@ContentChild ()
和@ContentChildren ()
访问主机元素的查询。迁移是依靠注入主机的Elementref.
。
不要将值分配给仅模板的变量
这种迁移是必要的,以避免对对象进行变异和分配未知属性。
其中的一个大在Angular 9版中,新的Ivy渲染器的更新是模板类型检查,这与这个新功能直接相关。在Angular version 9和Ivy渲染器之前,模板型变量基本上是一个任何
类型。这意味着,您可以在适合时突变对象及其属性。一般来说,这是一个反attern。
从Angular第9版和Ivy渲染器开始,仅限模板的变量将根据TypeScript编译器的模板类型检查严格度选项,成为强类型变量。因此,我们必须不要突变模板只变量。
让我们来看看一个例子做突变模板只变量:
<按钮# translateBtn(点击)=”translatebtn.translate =!translatebtn.translate”>翻译按钮><mat-accordion><mat-expansion-panel* Ngfor.=”让某人做某事”><mat-expansion-panel-header><mat-panel-title>{{person.fields.name | wookiee: translateBtn。翻译}}mat-panel-title>mat-expansion-panel-header>mat-expansion-panel>mat-accordion>
的translateBtn
与角度版本8的模板 - 仅变量是类型任何
。使用角度9,变量被强烈打字为HTMLButtonElement
。而且,这HTMLButtonElement
接口不有一个翻译
财产。
我们的目标是消除模板变量的突变,并依赖于组件属性和方法:
<按钮(点击)=”ontTranslate ()”>翻译按钮><mat-accordion><mat-expansion-panel* Ngfor.=”让某人做某事”><mat-expansion-panel-header><mat-panel-title>{{person.fields.name |wookiee:翻译mat-panel-title>mat-expansion-panel-header>mat-expansion-panel>mat-accordion>
我们已删除了仅模板的变量。注意模板变量表示法# translateBtn
已被删除。
现在,我们只是在组件类中实现属性和方法:
出口类PeopleListComponent.{translateToWookiee=假;onTranslate():空虚{这。translateToWookiee=!这。translateToWookiee;}}
TypeScript编译器更新(可选)
在更新到Angular version 9之前,你可以选择加入编译器更新,这将使你的更新更加无缝。更新你的tsconfig.json文件如下:
{“compilerOptions”:{“noimplicalany”:真正,“noImplicitReturns”:真正,“noImplicitThis”:真正,“nofallthroughcasesinswitch”:真正,“strictNullChecks”:真正}}
编译器要包含的关键标志是:
noImplicitAny
防止编译器暗示参数,变量或赋值的类型是类型的任何
,这是默认情况下,编译器无法推断出类型或未明确声明类型的代码。
noImplicitReturns
防止你在不被注意的情况下,也就是说,在你不知道的情况下,跌入一个函数能够返回任何
隐式。这可以确保您正确地返回正确的类型,无论您所在的代码分支是否返回值。
noImplicitThis
确保我们没有假设的价值这
。作为JavaScript开发人员,我们知道这
值取决于函数的执行上下文。这个编译器标志防止我们假设,或者允许编译器暗示上下文这
。
nofallthroughcasesinswitch
确保每一个案件
声明是由一个适当的保护打破
陈述防止案件落到了案件
声明。
strictnullchecks.
确保我们不允许两者未定义
和空值
除非在TypeScript中显式声明,否则值不能全局可用或可赋值。这个标志是高度推荐它可以防止可能产生的错误无效
合并和其他真假强制力。
渲染器
弃用
人们期待已久的这种变化,所以这并不奇怪。弃用的渲染器
最终从角度码布中删除。这意味着如果您的角度项目通过依赖注入依赖于弃用物渲染器
类,您需要迁移到的对象Renderer2
。
值得庆幸的是,这种迁移是通过的ng更新
命令我们要很快就会执行。所以,如果你是懒惰(像我一样),那么你现在可以跳过这个,让角update为您迁移它。
大多数方法都很容易更新渲染器
来Renderer2
,但那些不会为您修复的人。
请确保在更新后检查git差异渲染器
来Renderer2
迁移。
更新到最新的Angular 8补丁
在你更新到Angular version 9之前,你必须先更新到Angular version 8的最新稳定版本:
NG更新@ Angular / Core @ 8 @ Angular / Cli @ 8
更新到角度版本9
我们做了!我们已准备好将您的角度项目通过Angular版本9通过ng更新
:
ng更新@ Angular / Cli @ Angular / Core
虽然发布不是最终的,但目前在发布候选阶段,你需要附加- 下一个
旗:
ng update @angular/cli @angular/core——next
本地化(I18N)
如果你正在使用Angular的本地化(i18n)框架,那么你还需要使用ng添加
命令安装新@angular /本地化
包:
当你检查的差异Angular.Json.文件更新后,您还会注意到一个新的i18n
配置部分:
{“$架构”:”。/ node_modules / @angular / cli / lib / config / schema.json”,“版本”:1,“newprojectroot”:“项目”,“项目”:{“angular-v9”:{“国际化”:{“场所”:{“德”:{“翻译”:“src /地区/ messages.de.xlf”,“baseHref”:”“}}}}}}
你的一些更新Angular.Json.配置您应该考虑。
首先,指定sourcelocal.
财产。默认值是念头美国
,因此您需要根据源代码的区域设置为应用程序指定源语言环境:
{“$架构”:”。/ node_modules / @angular / cli / lib / config / schema.json”,“版本”:1,“newprojectroot”:“项目”,“项目”:{“angular-v9”:{“国际化”:{“sourceLocale”:“恩美”,“场所”:{“德”:{“翻译”:“src /地区/ messages.de.xlf”,“baseHref”:”“}}}}}}
其次,考虑更新baseHref
根据您的需求为每个区域设置配置。在大多数情况下,我们将使用唯一的子域或唯一路径为每个应用程序提供服务。
在我的用例中,我希望每个语言设置在唯一的路径上:
因此,我修改了baseHref
为了德
区域设置:
{“$架构”:”。/ node_modules / @angular / cli / lib / config / schema.json”,“版本”:1,“newprojectroot”:“项目”,“项目”:{“angular-v9”:{“国际化”:{“sourceLocale”:“恩美”,“场所”:{“德”:{“翻译”:“src /地区/ messages.de.xlf”,“baseHref”:“/ de /”}}}}}}
接下来,我的Angular version 8项目为每个区域设置使用了多个构建配置。根据我目前的经验,你可以删除这些,因为它们不再是必要的:
{“$架构”:”。/ node_modules / @angular / cli / lib / config / schema.json”,“版本”:1,“newprojectroot”:“项目”,“项目”:{“angular-v9”:{…“架构师”:{“构建”:{…“配置”:{“德”:{…},“production-de”:{…}}}}}}}
我移除了德
和生产德
配置。
最后,在项目中更新您的生产构建命令package.json文件包括新的- 光明
标记来构建所有的本地化:
{“名称”:“angular-v9”,“版本”:“0.0.0”,“脚本”:{“ng”:“ng”,…“服务:dist ":“HTTP-Server -P 8080 -C-1 Dist / Angular-V9”,“构建”:“ng build - prod --localize”,},
注意:
- 首先,我有一个新的
服务:dist.
命令我使用HTTP-Server节点模块提供我的生产构建的本地化版本。
- 其次,我更新了
建立
命令来包含new- 光明
标记以构建所有本地化。
让我也提到您可以创建其他配置来构建特定语言环境或一组语言环境。
更新后的清单
成功升级到Angular version 9后,我们需要做两件小事:
- 从不推荐的迁移
testbed.get()
新方法testbed.inject ()
方法。
- 删除不必要的
entryComponents
我们的财产@ngmodule()
装饰器对象。
迁移到testbed.inject()
发布Angular版本9更新,我们的第一个任务是迁移testbed.get()
来testbed.inject ()
。
之前:
描述('filmservice',()=>{让服务:filmservice.;beforeEach(()=>试验台。configuretestingModule.({进口:(HttpClientTestingModule]}));它('应该是创造的,()=>{服务=试验台。得到(filmservice.);期望(服务)。toBeTruthy();});});
后:
描述('filmservice',()=>{让服务:filmservice.;beforeEach(()=>试验台。configuretestingModule.({进口:(HttpClientTestingModule]}));它('应该是创造的,()=>{服务=试验台。注入<filmservice.>(filmservice.);期望(服务)。toBeTruthy();});});
注意:
- 我们改变
testbed.get()
来testbed.inject ()
- 函数返回的类型的泛型
注入()
方法。
删除entryComponents
使用Angular Version 9和新的常春藤渲染器,我们不需要明确地指示组件依赖图外部的组件的编译器。需要宣布的组件的一个很好的例子entryComponents
数组是对话框。
此更新很简单,谁不喜欢删除代码。刚删除entryComponents
数组的@ngmodule()
应用程序中的装饰器。
之前:
@ngmodule.({宣言:(PersonFilmsDialogComponent,personhomeplanetdialogcomponent.],entryComponents:(PersonFilmsDialogComponent,personhomeplanetdialogcomponent.]})出口类PeopleModule{}
在我们删除了不必要之后entryComponents
数组:
@ngmodule.({宣言:(PersonFilmsDialogComponent,personhomeplanetdialogcomponent.]})出口类PeopleModule{}
成功!
我们已成功更新为角度9和新的常春藤渲染引擎。
有问题吗?需要帮忙吗?让我知道!