首页 > 解决方案 > 如何在角度 9 中动态删除组件?

问题描述

我必须创建一个多选过滤器,该过滤器将接受要单击的多个选项值,以优化后端某些 get API 端点的响应。

每当用户点击一个选项时,一个“芯片”组件将被动态渲染以提醒用户:“嘿,你只是通过这个过滤结果,那个过滤选项”

在互联网上环顾四周,我发现了这个stackblitz

在此代码示例中,我以某种方式了解以下几行:

let componentFactory = this.CFR.resolveComponentFactory(ChildComponent);
let childComponentRef = this.VCR.createComponent(componentFactory);

我们在 a 中插入给定子组件的实例ViewContainerRef。找到一个有点像这样的对象:

_data: Object { renderElement: <!--  -->, componentView: undefined, viewContainer: {…}, … }
_elDef: Object { nodeIndex: 4, bindingIndex: 0, outputIndex: 1, … }
_embeddedViews: Array(5) [ {…}, {…}, {…}, … ] //here   
_view: Object { def: {…}, parent: {…}, state: 1036, … }

__embeddedViews对象下,动态生成的视图将被堆叠

稍后为了决定哪些视图将被删除,此 stackblitz 的创建者只需获取组件并制作 aViewContainerRef.indexOf(component)以获取存储组件的索引并验证动态生成的组件是否存在于该数组中。然后他/她只需删除视图调用this.ViewContainerRef.remove(index);

有趣的是,在我的实现中,当我记录我的时候,ViewContainerRef我得到了这个对象作为响应:

​_hostTNode: Object { type: 0, index: 23, injectorIndex: 34, … }
_hostView: Array(94) [ ..., {…}, 147, … ]
_lContainer: Array(12) [ <!-- 

芯片已按预期成功动态添加,但没有 _embeddedViews,因此我无法动态删除它们,因为ViewContainerRef.indexOf(chip)将始终返回 -1 作为“不,我这里没有“芯片”” 请有人启发我并展示什么我在这里做错了吗?

标签: javascriptangulartypescript

解决方案


您有这种不一致是因为您以错误的方式使用 ViewContainerRef API。

这是indexOf方法的签名:

abstract indexOf(viewRef: ViewRef): number;

这个签名在 Angular 更新期间从未改变。

您所指的 stackblitz 使用 Angular 6 版本,该版本在后台利用 ViewEngine,但在您的代码中,您使用的是 Ivy 编译器发挥作用的 Angular 9 及更高版本。

在 stackblitz 你有:

this.VCR.indexOf(componentRef as any);

这意味着您传递的是 ComponentRef 实例而不是 ViewRef 实例。它是偶然工作的,因为 indexOf 方法看起来像:

ViewContainerRef_.prototype.indexOf = function (viewRef) {
  return this._embeddedViews.indexOf(viewRef._view);
};

ComponentRef._view === ViewRef._viewViewEngine.

您应该ViewRef改为传递实例:

this.VCR.indexOf(componentRef.hostView)

分叉的 Stackblitz

该演示适用于 Ivy(您的特定情况),但它也适用于 ViewEngine。


推荐阅读