【问题标题】:How do I remove a component dynamically in angular 9?如何在角度 9 中动态删除组件?
【发布时间】:2021-01-17 18:04:28
【问题描述】:

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

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

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

在这个代码示例中,我明白在这几行中不知何故:

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

我们在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 的创建者只需获取组件并制作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 作为“不,我这里没有“芯片”” 请有人能启发我并在这里说明我做错了什么吗?

【问题讨论】:

  • 我快速查看了这一切,为什么不使用ngFor 来根据用户选择的过滤器(您可能存储在某个地方)来渲染您的芯片?对于您想要实现的目标而言,您当前的方法听起来太复杂了
  • 哇,我根本没有那样做。它表明我仍然在与角哈哈作斗争。如果您发布此答案,我将很乐意勾选正确。感谢您的帮助!
  • 并不是你问题的真正答案,所以我认为它不值得发布,只是实现相同结果的一种更简单的方法^^看看这个stackblitz.com/edit/…

标签: javascript angular typescript


【解决方案1】:

您有这种不一致是因为您以错误的方式使用 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)

Forked Stackblitz

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

【讨论】:

    猜你喜欢
    • 2019-02-20
    • 2018-05-17
    • 2021-12-15
    • 2020-10-06
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 2019-10-14
    相关资源
    最近更新 更多