Brian F爱
从专注于角图,Web技术以yobet英雄联盟及波特兰的Node.js的Google开发人员专家中学习。
广告 ·ultimatecourses.com.
用终极课程学习角度正确的方式“></a>
          </div>
          <article class=

懒人负载角9+组件

懒惰的装载组件与角9+刚刚变得更容易!

前往角v9

以前,懒惰加载了一个组件(不是一个懒惰的加载模块)在角度上需要一些了解角度的​​底层API,有些人可能会说,有点魔法。

Angular版本9引入了一个名为“常春藤”的新渲染引擎。这取代了以前称为“查看渲染器”的先前渲染引擎。使用常春藤的API是用于角度的,制作它许多更轻松地使用预时(AOT)编译和懒惰,并在运行时懒惰,加载和创建组件更容易编译组件。

在常春藤和角度9之前,我们必须:

  • 使用ngmodulefactoryloader.加载和编译模块,为其提供依赖的实例注射器
  • 然后我们使用RegryVeComponentFactory.注入的方法ComponentFactoryResolver.使用组件实例提供它。
  • 最后,我们可以通过该组件创建和呈现组件CreateComponent()的方法ViewContainerref.在dom。

为了简洁起见,我是将深入潜入延迟加载Angular V2至V8所需的代码的复杂性。相反,我会把你推荐给流行的英雄装载机模块由队伍建造在希罗多维夫斯。

存储库

为了跟随,你需要结账v9-懒人组件存储库的分支:

Git.克隆https://github.com/blode/angular-v9.git.Git.结帐V9-Lazy-Components

演示

具有角度9和常春藤的懒惰装载组件“></p>
            <h2>现有的陈述组成部分</h2>
            <p>在这个例子中,我目前有一个<code>PlanetComponent.</code>显示与a相关联的详细信息的实例<code>行星</code>。我使用这个组件才能显示一个人的家庭行星。例如,Luke Skywalker的家庭星球它Tatooine。</p>
            <p>这是我目前正在实施的模板<code>PlanetComponent.</code>, 位于<strong>src / app / feature / people / dialogs / person-planet-dialog / person-home-planet-distoge.component.html</strong>:</p>
            <div class=

<H1.垫对话标题>{{data.person.fields.name}}:家庭星球H1.><垫对话框内容><SWR-星球[行星]=行星|异步>SWR-星球>垫对话框内容><垫 - 对话框对齐=结束><按钮垫子按钮垫子对话关闭>按钮>垫 - 对话框>

而且,这是PlanetComponent.班级,位于SRC / APP /功能/人员/演示者/ Planet / Planet.comPonent.ts

@零件{选择器'SWR-Planet'TemplateURL.'./planet.Component.html'样式堡垒['./planet.component.scss']}出口PlanetComponent.{/ **显示的星球。* /@输入行星行星;}

PlanetComponent.有一个接受的单个输入行星显示。

带角v9的懒人加载组件

为了这项运动的目的,我想懒得加载PlanetComponent.

首先,我们需要删除现有声明的组件,并将其替换为此元件:

<H1.垫对话标题>{{data.person.fields.name}}:家庭星球H1.><垫对话框内容><ng-templation.>ng-templation.>垫对话框内容><垫 - 对话框对齐=结束><按钮垫子按钮垫子对话关闭>按钮>垫 - 对话框>

接下来,我们将访问ViewContainerref.与之相关使用@ViewChild()在我们的组件类中的装饰员。这位于SRC / APP /功能/人/人/对话/人家庭 - 行星对话框/人 - 家庭 - Planet-Dialog.comPonent.ts

出口personhomeplanetdialogcomponent.{/ ** Planet模板的View容器参考。* /@viewchild.Templateref.{ViewContainerref.}私人的PlanettemplateViewContainerref.ViewContainerref.;}

几件事要注意:

  • 首先,我们使用@ViewChild()装饰员为了创建视图查询Templateref.在我们的模板中的实例,我们使用该模板元件。
  • 其次,我们指定了选择可选的第二个论点@ViewChild()装饰函数。此可选参数是一个对象,以及我们可以指定的属性之一是属性。
  • 属性使我们能够从视图查询指定其他令牌以返回。在这种情况下,我想要参考ViewContainerref.实例。
  • 我们将使用它PlanettemplateViewContainerref.不久的类属性指示渲染引擎在哪里渲染我们延迟加载的组件。

下一步是注入一个实例ComponentFactoryResolver.类。

出口personhomeplanetdialogcomponent.{/ ** Planet模板的View容器参考。* /@viewchild.Templateref.{ViewContainerref.}私人的PlanettemplateViewContainerref.ViewContainerref.;构造函数私人的只读ComponentFactoryResolver.ComponentFactoryResolver.{}}

根据文件,ComponentFactoryResolver.是:

一个简单的注册表,将组件映射到生成的CompanicFactory类,该类可用于创建组件的实例。

下一步是:

  • 延迟加载组件包使用动态进口()功能。此函数需要对模块的路径并返回a诺言如果已解决,则提供模块。
  • 使用ComponentFactoryResolver.首先得到ComponentFactory.
  • 然后我们将使用CreateComponent()我们的方法ViewContainerref.创建和呈现DOM中的组件。
  • 最后,我们可以使用返回Componentref.实例修改实例的属性。
出口personhomeplanetdialogcomponent.{/ ** Planet模板的View容器参考。* /@viewchild.Templateref.{ViewContainerref.}私人的PlanettemplateViewContainerref.ViewContainerref.;构造函数私人的只读ComponentFactoryResolver.ComponentFactoryResolver.{}私人的LazyloadPlanet.行星行星空虚{进口'../../presenters/planet/planet.component'然后{PlanetComponent.}=>{const零件=这个ComponentFactoryResolver.RegryVeComponentFactory.PlanetComponent.;constComponentref.=这个PlanettemplateViewContainerref.createComponent.零件;Componentref.实例行星=行星;};}}

让我们快速审查LazyloadPlanet()方法:

  • 首先,我们使用进口()功能动态导入模块(ES6模块,而不是NgModule)。
  • 这回归A.诺言用模块解析。
  • 我正在使用对象破坏来访问PlanetComponent.在模块中导出的类。
  • 使用ResolveComponentFactory()注射方法ComponentFactoryResolver.班级获得ComponentFactory.实例为PlanetComponent.
  • 使用CreateComponent()方法的方法PlanettemplateViewContainerref.创建和呈现附加的组件ViewContainerref.
  • CreateComponent()方法返回A.Componentref.实例,有一个实例引用组件实例的属性。
  • 最后,我们指定了行星我们的财产PlanetComponent.实例提供必要的数据来显示信息的信息行星

以下是包含获取的完整源代码行星为了

出口personhomeplanetdialogcomponent.实施ondestroyoninit.{/ ** Planet模板的View容器参考。* /@viewchild.Templateref.{ViewContainerref.}PlanettemplateViewContainerref.ViewContainerref.;/ **当组件被销毁时取消订阅可观察流。* /私人的取消订阅=学科;构造函数私人的只读ComponentFactoryResolver.ComponentFactoryResolver.@注入mat_dialog_data.上市数据{}私人的只读行星服务行星服务{}ngondestroy{这个取消订阅下一个;这个取消订阅完成;}ngoninit.{这个行星服务getplanetforperson.这个数据龙头行星=>这个LazyloadPlanet.行星take这个取消订阅订阅;}私人的LazyloadPlanet.行星行星空虚{进口'../../presenters/planet/planet.component'然后{PlanetComponent.}=>{const零件=这个ComponentFactoryResolver.RegryVeComponentFactory.PlanetComponent.;constComponentref.=这个PlanettemplateViewContainerref.createComponent.零件;Componentref.实例行星=行星;};}}

这就是我们如何使用Angular版本9加载组件的方式!

懒惰将多个组件加载到模板中

在上面的示例中,您可能已经注意到我们正在使用Templateref.查询@ViewChild()访问这一点模板参考。如果您懒惰将多个组件加载到模板中,则此策略将无法正常工作。

这里的解决方案是使用多核具有模板参考变量的元素:

<ng-container.#PersonContainer.>ng-container.><ng-container.#planetcontainer.>ng-container.>

我喜欢使用为此而不是污染DOM的元素

(或其他)元素。

然后,我可以将模板参考变量名称指定给@ViewChild()查询获取ViewContainerref.对于每个容器:

出口personhomeplanetdialogcomponent.{/ **人员容器的视图集装箱参考。* /@viewchild.'人物联网'{ViewContainerref.}私人的personviewcontainerreref.ViewContainerref.;/ ** Planet容器的视图容器参考。* /@viewchild.'PlanetContainer'{ViewContainerref.}私人的PlanetViewContainerref.ViewContainerref.;}

现在我可以根据需要延迟加载组件,然后在相应的情况下创建和呈现相应的组件ViewContainerref.

依赖性

如果您的延迟加载的组件有需要注入组件类的依赖关系构造函数()功能?

答案是:

  • 如果已保证依赖性已通过该依赖性已加载提供者Array An.@ngmodule(),或通过提供课堂上的财产@injectable()装饰师,然后它应该只是工作。当然,如果尚未提供依赖项,则依赖项注入将失败,错误:nullinjectorerror:XYZService没有提供者!
  • 如果尚未提供依赖项,则我们可以指定提供者阵列在@零件()懒惰加载组件的元数据。

这是一个使用的例子提供者组件元数据中的属性指定延迟加载组件的依赖项:

@零件{选择器'SWR-Planet'TemplateURL.'./planet.Component.html'样式堡垒['./planet.component.scss']提供者[filmservice.]}出口PlanetComponent.{/ **显示的星球。* /@输入行星行星;构造函数filmservice.filmservice.{}}

注意:

  • 使用提供者物业在@零件()装饰器我们可以指示依赖注入为此组件创建提供程序(以及在此级别的依赖树)。
  • 我们现在可以通过组件类注入依赖项构造函数()功能。

模块

如果您的延迟加载的组件依赖于其他模块,该怎么办?例如,如果你需要什么FormsModule.和/或反应omformodule如果您的组件是一种形式?

如果我们试图使用NGForm.在我们的模板中,我们将收到错误:错误:没有导出的指令'ngform'。问题是我们的组件模板依赖于公开导出的指令FormsModule.

答案是我们包括一个ngmodule.在与组件的同一文件中并指定必要的文件进口对于组件:

@零件{选择器'SWR-Planet'TemplateURL.'./planet.Component.html'样式堡垒['./planet.component.scss']}出口PlanetComponent.{/ **显示的星球。* /@输入行星行星;}@ngmodule.{宣言[PlanetComponent.]进口[FormsModule.反应omformodule]}PlanetComponentModule.{}

注意:

  • PlanetComponent.依靠两种FormsModule.反应omformodule
  • 我们创造了一个ngmodule.在与延迟加载的组件相同的文件中。
  • 我们指定了宣言属性引用组件类;在这种情况下PlanetComponent.类。
  • 我们指定了进口具有需要导入延迟加载组件的模块数组的属性。

结论

使用Angular Version 9和新的常春藤编译和渲染管道我们可以延迟加载,创建和渲染角分量。

Brian F爱

嗨,我是布莱恩。我对类型名称,Angular和node.js感兴趣我嫁给了我最好的朋友邦妮,我住在波特兰和我滑雪(很多)。