如何在角度9中动态移除组件?

时间:2020-10-02 01:28:52

标签: javascript angular typescript

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

每当用户单击一个选项时,就会自动渲染一个“芯片”组件以通知用户:“嘿,您只是通过此过滤结果以及那个过滤选项”

环顾互联网,我发现了这个stackblitz

在此代码示例中,我了解到以下几行:

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

我们在ViewContainerRef内插入给定子组件的实例。 我打开控制台,然后console.log(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对象下,动态生成的视图将被堆叠

稍后决定将要删除的视图,此堆叠闪电的创建者仅获取组件并进行ViewContainerRef.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,因为“不,我在这里没有筹码” 请有人能启发我并在这里显示我在做什么错吗?

1 个答案:

答案 0 :(得分:3)

您的不一致之处在于您使用ViewContainerRef API的方式错误。

这是indexOf方法的签名:

abstract indexOf(viewRef: ViewRef): number;

此签名在Angular更新期间从未更改。

您所指的堆叠闪电战使用的是在后台利用ViewEngine的Angular 6版本,但是在您的代码中,您使用的是使用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._view in ViewEngine

您应该传递ViewRef实例:

this.VCR.indexOf(componentRef.hostView)

Forked Stackblitz

该演示适用于Ivy(您的特殊情况),但它也可以在ViewEngine中使用。