[英]How do I remove a component dynamically in angular 9?
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.我必须创建一个多选过滤器,它可以接受要单击的多选项值,以便优化后端某些 get API 端点的响应。
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"每当用户点击一个选项时,一个“芯片”组件将动态呈现以了解用户:“嘿,你只是通过这个和那个过滤器选项过滤结果”
Looking around in internet I found this stackblitz在互联网上环顾四周,我发现了这个stackblitz
In this code sample I understand that somehow in this lines:在此代码示例中,我以某种方式理解这一行:
let componentFactory = this.CFR.resolveComponentFactory(ChildComponent);
let childComponentRef = this.VCR.createComponent(componentFactory);
we insert an instance of a given child component inside a ViewContainerRef
.我们在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, … }
where under __embeddedViews
object the dynamically generated views will be stack up在__embeddedViews
对象下,动态生成的视图将堆叠起来
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.后来决定删除哪些视图,这个stackblitz的创建者只是获取组件并创建一个ViewContainerRef.indexOf(component)
来获取存储组件的索引并验证动态生成的组件是否存在于该数组中。 Then he/she just delete the view calling this.ViewContainerRef.remove(index);
然后他/她只是删除调用this.ViewContainerRef.remove(index);
的视图this.ViewContainerRef.remove(index);
Funny thing, in my implementation when I log my ViewContainerRef
I get this object as response:有趣的是,在我的实现中,当我记录我的ViewContainerRef
我得到这个对象作为响应:
_hostTNode: Object { type: 0, index: 23, injectorIndex: 34, … }
_hostView: Array(94) [ ..., {…}, 147, … ]
_lContainer: Array(12) [ <!--
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?芯片按预期成功动态添加,但没有 _embeddedViews,因此我无法动态删除它们,因为ViewContainerRef.indexOf(chip)
将始终返回 -1 为“不,我这里没有“芯片””请可以有人启发我并展示我在这里做错了什么?
You have such inconsistency because you're using ViewContainerRef API in a wrong way.你有这样的不一致是因为你以错误的方式使用 ViewContainerRef API。
Here's the signature of indexOf method:这是indexOf方法的签名:
abstract indexOf(viewRef: ViewRef): number;
This signature never changed during Angular updates.这个签名在 Angular 更新期间从未改变。
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 使用 Angular 6 版本,该版本在幕后利用 ViewEngine,但在您的代码中,您使用的是 Angular 9 及更高版本,其中 Ivy 编译器发挥作用。
In stackblitz you have:在stackblitz你有:
this.VCR.indexOf(componentRef as any);
Meaning that you're passing ComponentRef instance not ViewRef instance.这意味着您正在传递 ComponentRef 实例而不是 ViewRef 实例。 It works by accident because indexOf method looks like:它的工作是偶然的,因为 indexOf 方法看起来像:
ViewContainerRef_.prototype.indexOf = function (viewRef) {
return this._embeddedViews.indexOf(viewRef._view);
};
and和
ComponentRef._view === ViewRef._view
in ViewEngine
. ComponentRef._view === ViewRef._view
中的ViewEngine
。
You should be passing ViewRef
instance instead:您应该改为传递ViewRef
实例:
this.VCR.indexOf(componentRef.hostView)
The demo works with Ivy(your particular case) but it will also work in ViewEngine.该演示适用于 Ivy(您的特定情况),但也适用于 ViewEngine。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.