Brian F爱据/a>
广告据/span> ·ultimatecourses.com.据/div> 用终极课程学习角度正确的方式“></a>
          </div>
          <article class=

懒人负载角9+组件据/H1.>据time class="PostContent__Time-sc-1n9cz17-1 jqeDlO">2019年12月13日据/time>

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

前往角v9据/h2>

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

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

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

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

为了简洁起见,我是据em>不是据/em>将深入潜入延迟加载Angular V2至V8所需的代码的复杂性。相反,我会把你推荐给流行的据a href="https://www.npmjs.com/package/@herodevs/hero-loader">英雄装载机模块据/a>由队伍建造在希罗多维夫斯。据/p>

存储库据/h2>

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

Git.据/span>克隆https://github.com/blode/angular-v9.git.据span class="token function">Git.据/span>结帐V9-Lazy-Components据/code>

演示据/h2>

具有角度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.据/span>垫对话标题据/span>>{{data.person.fields.name}}:家庭星球据span class="token tag">H1.据/span>>垫对话框内容据/span>>SWR-星球据/span>[行星]据/span>=“据/span>行星|异步据span class="token punctuation">“据/span>>SWR-星球据/span>>垫对话框内容据/span>>垫 - 对话框据/span>对齐据/span>=“据/span>结尾据span class="token punctuation">“据/span>>按钮据/span>垫子按钮据/span>垫子对话关闭据/span>>关闭据span class="token tag">按钮据/span>>垫 - 对话框据/span>>

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

@据span class="token function">成分据/span>(据/span>{选择器据span class="token operator">:据/span>'SWR-Planet'据/span>那据/span>TemplateURL.据span class="token operator">:据/span>'./planet.Component.html'据/span>那据/span>样式堡垒据span class="token operator">:据/span>['./planet.component.scss'据/span>]})据/span>出口据/span>班级据/span>PlanetComponent.据/span>{/ **显示的星球。* /@据span class="token function">输入据/span>(据/span>)据/span>行星据span class="token operator">:据/span>行星据span class="token punctuation">;据/span>}

这据code>PlanetComponent.据/code>有一个接受的单个输入据code>行星据/code>显示。据/p>

带角v9的懒人加载组件据/h2>

为了这项运动的目的,我想懒得加载据code>PlanetComponent.据/code>。据/p>

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

H1.据/span>垫对话标题据/span>>{{data.person.fields.name}}:家庭星球据span class="token tag">H1.据/span>>垫对话框内容据/span>>ng-templation.据/span>>ng-templation.据/span>>垫对话框内容据/span>>垫 - 对话框据/span>对齐据/span>=“据/span>结尾据span class="token punctuation">“据/span>>按钮据/span>垫子按钮据/span>垫子对话关闭据/span>>关闭据span class="token tag">按钮据/span>>垫 - 对话框据/span>>

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

出口据/span>班级据/span>personhomeplanetdialogcomponent.据/span>{/ ** Planet模板的View容器参考。* /@据span class="token function">viewchild.据/span>(据/span>Templateref.据span class="token punctuation">那据/span>{读据span class="token operator">:据/span>ViewContainerref.据span class="token punctuation">})据/span>私人的据/span>PlanettemplateViewContainerref.据span class="token operator">:据/span>ViewContainerref.据span class="token punctuation">;据/span>}

几件事要注意:据/p>

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

下一步是注入一个实例据code>ComponentFactoryResolver.据/code>班级。据/p>

出口据/span>班级据/span>personhomeplanetdialogcomponent.据/span>{/ ** Planet模板的View容器参考。* /@据span class="token function">viewchild.据/span>(据/span>Templateref.据span class="token punctuation">那据/span>{读据span class="token operator">:据/span>ViewContainerref.据span class="token punctuation">})据/span>私人的据/span>PlanettemplateViewContainerref.据span class="token operator">:据/span>ViewContainerref.据span class="token punctuation">;据/span>构造函数据/span>(据/span>私人的据/span>只读据/span>ComponentFactoryResolver.据span class="token operator">:据/span>ComponentFactoryResolver.据/span>)据/span>{}}

根据文件,据code>ComponentFactoryResolver.据/code>是:据/p>

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

下一步是:据/p>

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

让我们快速审查据code>LazyloadPlanet()据/code>方法:据/p>

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

以下是包含获取的完整源代码据code>行星据/code>为了据code>人据/code>:据/p>

出口据/span>班级据/span>personhomeplanetdialogcomponent.据/span>实施据/span>ondestroy据/span>那据/span>oninit.据span class="token punctuation">{/ ** Planet模板的View容器参考。* /@据span class="token function">viewchild.据/span>(据/span>Templateref.据span class="token punctuation">那据/span>{读据span class="token operator">:据/span>ViewContainerref.据span class="token punctuation">})据/span>PlanettemplateViewContainerref.据span class="token operator">:据/span>ViewContainerref.据span class="token punctuation">;据/span>/ **当组件被销毁时取消订阅可观察流。* /私人的据/span>取消订阅据span class="token operator">=新的据/span>主题据/span>(据/span>)据/span>;据/span>构造函数据/span>(据/span>私人的据/span>只读据/span>ComponentFactoryResolver.据span class="token operator">:据/span>ComponentFactoryResolver.据span class="token punctuation">那据/span>@据span class="token function">注入据/span>(据/span>mat_dialog_data.据/span>)据/span>民众据/span>数据据span class="token operator">:据/span>{人据span class="token operator">:据/span>人据span class="token punctuation">}那据/span>私人的据/span>只读据/span>行星服务据span class="token operator">:据/span>行星服务据/span>)据/span>{}ngondestroy据/span>(据/span>)据/span>{这个据/span>。据/span>取消订阅据span class="token punctuation">。据/span>下一个据/span>(据/span>)据/span>;据/span>这个据/span>。据/span>取消订阅据span class="token punctuation">。据/span>完全的据/span>(据/span>)据/span>;据/span>}ngoninit.据/span>(据/span>)据/span>{这个据/span>。据/span>行星服务据span class="token punctuation">。据/span>getplanetforperson.据/span>(据/span>这个据/span>。据/span>数据据span class="token punctuation">。据/span>人据span class="token punctuation">)据/span>。据/span>管道据/span>(据/span>轻敲据/span>(据/span>行星据/span>=>据/span>这个据/span>。据/span>LazyloadPlanet.据/span>(据/span>行星据span class="token punctuation">)据/span>)据/span>那据/span>take据/span>(据/span>这个据/span>。据/span>取消订阅据span class="token punctuation">)据/span>)据/span>。据/span>订阅据/span>(据/span>)据/span>;据/span>}私人的据/span>LazyloadPlanet.据/span>(据/span>行星据span class="token operator">:据/span>行星据span class="token punctuation">)据/span>:据/span>空白据/span>{进口据/span>(据/span>'../../presenters/planet/planet.component'据/span>)据/span>。据/span>然后据/span>(据/span>(据/span>{PlanetComponent.据span class="token punctuation">})据/span>=>据/span>{const据/span>成分据span class="token operator">=这个据/span>。据/span>ComponentFactoryResolver.据span class="token punctuation">。据/span>RegryVeComponentFactory.据/span>(据/span>PlanetComponent.据span class="token punctuation">)据/span>;据/span>const据/span>Componentref.据span class="token operator">=这个据/span>。据/span>PlanettemplateViewContainerref.据span class="token punctuation">。据/span>createComponent.据/span>(据/span>成分据span class="token punctuation">)据/span>;据/span>Componentref.据span class="token punctuation">。据/span>实例据span class="token punctuation">。据/span>行星据span class="token operator">=行星据span class="token punctuation">;据/span>})据/span>;据/span>}}

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

懒惰将多个组件加载到模板中据/h2>

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

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

ng-container.据/span>#PersonContainer.据/span>>ng-container.据/span>>ng-container.据/span>#planetcontainer.据/span>>ng-container.据/span>>

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

据/code>(或其他)元素。据/p>

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

出口据/span>班级据/span>personhomeplanetdialogcomponent.据/span>{/ **人员容器的视图集装箱参考。* /@据span class="token function">viewchild.据/span>(据/span>'人物联网'据/span>那据/span>{读据span class="token operator">:据/span>ViewContainerref.据span class="token punctuation">})据/span>私人的据/span>personviewcontainerreref.据span class="token operator">:据/span>ViewContainerref.据span class="token punctuation">;据/span>/ ** Planet容器的视图容器参考。* /@据span class="token function">viewchild.据/span>(据/span>'PlanetContainer'据/span>那据/span>{读据span class="token operator">:据/span>ViewContainerref.据span class="token punctuation">})据/span>私人的据/span>PlanetViewContainerref.据span class="token operator">:据/span>ViewContainerref.据span class="token punctuation">;据/span>}

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

依赖性据/h2>

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

答案是:据/p>

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

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

@据span class="token function">成分据/span>(据/span>{选择器据span class="token operator">:据/span>'SWR-Planet'据/span>那据/span>TemplateURL.据span class="token operator">:据/span>'./planet.Component.html'据/span>那据/span>样式堡垒据span class="token operator">:据/span>['./planet.component.scss'据/span>]那据/span>提供者据span class="token operator">:据/span>[filmservice.据span class="token punctuation">]})据/span>出口据/span>班级据/span>PlanetComponent.据/span>{/ **显示的星球。* /@据span class="token function">输入据/span>(据/span>)据/span>行星据span class="token operator">:据/span>行星据span class="token punctuation">;据/span>构造函数据/span>(据/span>filmservice.据span class="token operator">:据/span>filmservice.据/span>)据/span>{}}

笔记:据/p>

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

模块据/h2>

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

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

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

@据span class="token function">成分据/span>(据/span>{选择器据span class="token operator">:据/span>'SWR-Planet'据/span>那据/span>TemplateURL.据span class="token operator">:据/span>'./planet.Component.html'据/span>那据/span>样式堡垒据span class="token operator">:据/span>['./planet.component.scss'据/span>]})据/span>出口据/span>班级据/span>PlanetComponent.据/span>{/ **显示的星球。* /@据span class="token function">输入据/span>(据/span>)据/span>行星据span class="token operator">:据/span>行星据span class="token punctuation">;据/span>}@据span class="token function">ngmodule.据/span>(据/span>{宣言据span class="token operator">:据/span>[PlanetComponent.据span class="token punctuation">]那据/span>进口据span class="token operator">:据/span>[FormsModule.据span class="token punctuation">那据/span>反应omformodule据span class="token punctuation">]})据/span>班级据/span>PlanetComponentModule.据/span>{}

笔记:据/p>

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

结论据/h2>

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

Brian F爱据/h3>

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