点击事件在运行时添加 Angular 组件的最佳方法
Posted
技术标签:
【中文标题】点击事件在运行时添加 Angular 组件的最佳方法【英文标题】:Best Way To Add Angular Component At RunTime On Click Event 【发布时间】:2019-12-24 03:31:45 【问题描述】:我正在构建的网站有多个组件。在“主页”页面组件上,当用户单击按钮向页面添加内容时,我想将他们选择的组件附加到“主页”组件。我已经研究并发现了 3 种方法,但我想知道考虑这种功能的最佳实践是什么。该页面将使用其他用户已经添加的一些组件进行初始化。我希望用户能够在那里添加组件。
Angular 说我应该这样做: https://angular.io/guide/dynamic-component-loader
Angular Material 说我应该这样做: https://material.angular.io/cdk/portal/overview
我个人也期望这样(可行),但我认为这不是“最佳实践”:
所以当用户点击这个标签时,它会触发 append 方法:
<a class="dropdown-item" href="#!" (click)="prependMedia('elementOne')">ElementOne</a>
该方法在组件的 TS 文件中调用它,有效地将新元素推送到数组中。然后列出的 html 将监视添加的新元素并将组件放入 ngFor:
TypeScript 文件:
mediaElements: any[] = [];
element: any =
name: 'elementOne',
data: 'data'
;
constructor()
ngOnInit()
prependMedia(type: string)
console.log(type);
this.mediaElements.push(this.element);
将新模型添加到 mediaElements 数组后添加组件的 HTML 文件:
<div *ngFor="let element of mediaElements" [(ngModel)]="mediaElements">
<div *ngIf="element.name == 'elementOne'">
<app-elementone></app-elementone>
</div>
</div>
我的问题: 我对 ngFor 使用的方法有什么问题?不是以自以为是的方式,而是在技术上。 当用户单击按钮将组件添加到页面时,将组件添加到 DOM 的“最佳实践”方式是什么?为什么?不是以固执己见的方式,而是技术上或来自 Angular 团队的证据。
我最初打算使用我在代码中的显示方式,但现在我找到了 Angular 方式和 Angular Material 方式,我正在寻找关于最佳方式的事实。
请指教?由于有些人认为这对意见过于开放,因此保持技术性会有所帮助。
如果您需要任何进一步的说明,请告诉我。
谢谢你, 埃里克
【问题讨论】:
我认为 for 循环是最简单的方法,只有在它不起作用的情况下,如果您不知道用户可以使用哪些组件,那么您需要使用动态组件解决方案 @Xesenix 我认为我挂断的部分原因是,我同意这是最简单的,但是有什么原因使它成为一种不好的做法吗? Angular 和 Angular Material 创建了它们的方法,而不是我所写的,一定是有原因的。我确实知道他们将添加的每个元素的类型(因为我为每个动态组件都有一个模型,并且他们只能添加集合类型) 在使用这个简单的解决方案大约 1,5-2 年之后,我可以从我的经验中看出,除了将渲染组件与渲染它们的模块耦合之外,我没有看到任何使它成为反模式的东西。因此,这取决于您需要在多大程度上使用该模式。如果仅在少数地方我会说处理动态组件的额外工作在其他情况下是不值得的,例如当您创建可重用组件时,可能会使用在渲染循环上下文中不知道的组件与动态组件一起使用。跨度> 【参考方案1】:您使用的*ngFor
语法是标准方法
动态组件更适合您不知道可能需要哪些组件的情况。这方面的一个示例是模态对话框,其中模态可能必须显示任何类型的组件 - 或者如果您有一个第三方库来显示库用户传入的组件
如果你不需要外部div
,你可以使用:
<ng-container *ngFor="let element of mediaElements">
</ng-container>
如果您有<div *ngIf="element.name == 'elementOne'">
,您可以使用*ngSwitch
,其中switch case 将是元素名称 - 如果您需要渲染一些不同 组件,这将适合。 Angular Docs 网站上有一个很好的 ngSwitch example,这与您正在做的事情非常接近(据我所知)
注意:我不确定您为什么需要 ngModel
绑定。最好从模板调度事件,并更新组件中的绑定
【讨论】:
感谢您的详细解答!此外,为了指出开关将是一种更好的处理方式......也适用于 ngModel 信息......我已将此标记为正确答案,因为它详细说明了我需要知道的内容......我想知道为什么现在 Angular Material Portals 和 Angular 的 Dynamic Component 文档之间存在差异。这只是好奇,尽管这有很大帮助。谢谢! CDK Portal 和动态组件文档的区别在于 CDK 是一个可选库。它为诸如动态组件之类的 Angular 功能添加了包装器,使它们更易于使用 感谢您的区别。我知道 CDK 是可选的,因为它是 Angular Material 的一部分。不过,我不知道 Portal 是动态组件功能的包装器。以上是关于点击事件在运行时添加 Angular 组件的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章
使用 Angular,如何在点击时动态添加组件? (不止一个)