javascript - 如何在 Angular 9 中动态删除组件?

标签 javascript angular typescript

我必须创建一个多选过滤器来接受要单击的多个选项值,以便优化后端某些获取 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, … }

动态生成的 View 将在 __embeddedViews 对象下堆叠

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

删除 View

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

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

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

最佳答案

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

这是 indexOf 的签名方法:

abstract indexOf(viewRef: ViewRef): number;

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

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

在 stackblitz 中你有:

this.VCR.indexOf(componentRef as any);

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

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

ViewEngine 中的ComponentRef._view === ViewRef._view

您应该传递 ViewRef 实例:

this.VCR.indexOf(componentRef.hostView)

<强> Forked Stackblitz

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

关于javascript - 如何在 Angular 9 中动态删除组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64165149/

相关文章:

typescript - 如何将实例变量传递给 typescript 装饰器参数?

javascript - 在 Typescript 前端和 NodeJs 后端之间共享 js 对象的最佳方式

Angular2 - 具有登录结构的路由器导出

typescript - 如何在TypeScript Express服务器中将字符串解码/编码为base64

javascript - 用更好的东西代替 Switch-Case?

javascript - 如何定义新路由器?

typescript - Angular 2 RC2 单选按钮绑定(bind)损坏

angular - "No provider for AlertController!"npm ionic Angular

JavaScript 检查字符串中是否包含字母

javascript - JavaScript 数组如何在内部调整大小?