跳至正文
首页 » 博客 » Dynamically Load Angular Components

Dynamically Load Angular Components

文章: Jared Fineman

静态是使东西附着在你衣服上的力量; 它也是传统上在Angular html文件中创建的组件类型。虽然静态组件大部分时间都能完成工作,但当涉及到某些复杂的场景时,我们需要我们的组件更动态地行动。在本文中,我希望探讨如何动态加载组件,以及其背后的基本原理。

让我们从问题开始。我们有各种类型的组件,我们希望根据用户在UI中进行的选择来显示。选择是动态的,然而,角组件不是; 那么,我们如何能够在我们的视图中的组件之间切换?基本的解决方案是用ngIf指令注释我们的静态组件,从而完全规避问题。

<container-element><some-element * ngIf = "myChoice === filterComponent">...</some-element><some-element * ngIf = "myChoice === sortingComponent">...</some-element><some-element * ngIf = "myChoice === editingComponent">...</some-element><ng-container * ngIf = "myChoice === movableComponent"></ng-container></container-element>

我们甚至可以把它踢一个档次,并使用ngSwitch指令来更清晰地查看我们的DOM。

<container-element [ngSwitch]= "myChoice"><some-element * ngSwitchCase = "filterComponent">...</some-element><some-element * ngSwitchCase = "sortingComponent">...</some-element><some-element * ngSwitchCase = "editingComponent">...</some-element><ng-container * ngSwitchCase = "movableComponent"></ng-container><some-element * ngSwitchDefault>...</some-element></container-element>

当我们的选择接近四到五个组件时,所有这些都很好,但是如果我们处理的是像仪表板这样的东西,它有五十个组件需要动态实例化呢?维护这种类型的switch语句可能意味着我们的代码质量的灯熄灭。

这导致我们的第二种方法,创建一个指令,将动态加载我们的组件。我们像任何其他指令一样开始,确保我们包含一个输入属性,该属性将包含创建组件所需的所有信息。

@ 指令 ({ selector: '[loader]' })导出类LoaderDirective {组件: myComponent;@ Input()私有componentContext: ComponentContext;
构造函数 (private _elref: ElementRef,private _viewContainerRef: ViewContainerRef,private _componentFactoryResolver: ComponentFactoryResolver) {}}

注意ComponentFactoryResolverViewContainerRef类被注入到我们的构造函数中,这些类将负责创建我们的组件并将其集成到我们的指令视图中。

我们的指令从创建我们的组件工厂开始,这是一种奇特的说法,即知道如何构建我们的组件的对象。

let componentFactory = this._componentFactoryResolver。resolveComponentFactor y(this.componentContext.com组件);

如果我们查看源代码,我们会看到resolveComponentFactory方法采用了一个类型为… well type的参数。类型类是每个组件的基类,换句话说,在此处插入组件的类名以创建其工厂。

抽象resolveComponentFactory<T>(component: Type<T>): ComponentFactory<T>;

然后,我们继续清除指令的视图,以避免可能的重复,然后创建我们的组件。

this._viewContainerRef.clear();
让componentRef =this._viewContainerRef.createComponent(componentFactory);
this.com ponent = (<IComponent>componentRef.instance);this.component.com ponentContext = this.com ponentContext;

虽然viewContainerRef对象的createComponent函数调用足以在DOM中实例化我们的组件,但我们创建一个变量来保存对组件的引用,以便传入其配置所需的任何值。巧妙的是,这个变量充当我们组件的实时引用,任何更改的值都将触发组件的检测系统并在其视图中绑定值。

最后,我们将loader指令放在ng-template标签上,并通过componentContext输入属性将值传递给组件

<ng-模板装载机[componentContext]="{组件: 组件,名称: 名称,颜色: 颜色,parentId: parentId}"></ng-template>

关于动态加载的组件需要注意的另一件事是,由于它们的选择器在DOM中找不到,因此Angular编译器不会为它们生成ComponentFactory。因此,为了绕过这个问题,我们需要在我们模块的entryComponents集合中注册我们的组件

可以想象,能够动态加载组件是非常强大的工具,甚至可以在数据驱动模型中利用,在该模型中,视图将底层数据与其相应的组件编织在一起。

如果你喜欢这篇文章,请喜欢它并分享它。此外,如果你还没有Infragistics点燃UI的角度检查,一定要这样做!他们有50个基于材质的Angular组件,可以帮助您更快地编写快速的web应用程序。

</p