如何在 angular 9 中动态删除组件? [英] How do I remove a component dynamically in angular 9?

查看:79
本文介绍了如何在 angular 9 中动态删除组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to create a multi select filter that would accept multi option values to be clicked, in order to refine the response of some get API endpoint on the backend.

每当用户点击一个选项时,就会出现一个筹码".组件将动态呈现以了解用户:嘿,您只需通过此过滤结果,以及该过滤器选项"

Whenever a user click on a option, a "chip" component would be dynamically render to aware the user: "hey you just filter the result by this, and that filter option"

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

Looking around in internet I found this stackblitz

在此代码示例中,我以某种方式理解这一行:

In this code sample I understand that somehow in this lines:

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

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

we insert an instance of a given child component inside a ViewContainerRef. find a object somewhat like this:

_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 对象下动态生成的视图将堆叠起来

where under __embeddedViews object the dynamically generated views will be stack up

稍后决定删除哪些视图,这个stackblitz的创建者只需获取组件并创建一个ViewContainerRef.indexOf(component)来获取存储组件的索引并验证动态生成的组件存在于该数组中.然后他/她只是删除调用 this.ViewContainerRef.remove(index);

Later to decide which views will be deleted, the creator of this stackblitz just get the component and make a ViewContainerRef.indexOf(component) to get the index in which the component is stored and verify that that the dynamically generated component exist in that array. Then he/she just delete the view calling this.ViewContainerRef.remove(index);

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

Funny thing, in my implementation when I log my ViewContainerRef I get this object as response:

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

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

The chips are successfully added dynamically as expected, but there is no _embeddedViews, so I cannot remove them dynamically because ViewContainerRef.indexOf(chip) will always return -1 as "no, I don't have a "chip" here" Please can someone enlighten me and show what I'm doing wrong here?

推荐答案

你有这样的不一致是因为你以错误的方式使用了 ViewContainerRef API.

You have such inconsistency because you're using ViewContainerRef API in a wrong way.

这是indexOf方法的签名:

abstract indexOf(viewRef: ViewRef): number;

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

This signature never changed during Angular updates.

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

The stackblitz you're referring to uses Angular 6 version that leverage ViewEngine under the hood but in your code you're using Angular 9 and above version where Ivy compiler comes into play.

在stackblitz中你有:

In stackblitz you have:

this.VCR.indexOf(componentRef as any);

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

Meaning that you're passing ComponentRef instance not ViewRef instance. It works by accident because indexOf method looks like:

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

ComponentRef._view === ViewRef._viewViewEngine 中.

您应该改为传递 ViewRef 实例:

You should be passing ViewRef instance instead:

this.VCR.indexOf(componentRef.hostView)

分叉 Stackblitz

该演示适用于 Ivy(您的特殊情况),但也适用于 ViewEngine.

The demo works with Ivy(your particular case) but it will also work in ViewEngine.

这篇关于如何在 angular 9 中动态删除组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆