Angular 8 - 删除 ng-component 标签 - 表行模板

2024-05-03

我有一个灵活的表格组件,有两种模式:

  1. 普通表 - 有效
  2. 自定义行模板 - 这不是因为角度添加<ng-component> tag

逻辑输入TableComponent并不重要,模板是:

<table class="table table-hover table-sm table-middle table-crud">
    <thead role="rowgroup">
        <!-- SNIP -->
    </thead>
    <tbody *ngIf="customRowComponent" crud-table-row-renderer
            [renderComponent]="customRowComponent"
            [rows]="rows"
            [columns]="columns"
            [config]="config"
            [parent]="parent"
            [rowActions]="rowActions"
            [cellActionEmitter]="cellActionEmitter"
            [selectedRows]="selectedRows">
    </tbody>
    <tbody *ngIf="!customRowComponent" crud-table-row
            [rows]="rows"
            [columns]="columns"
            [config]="config"
            [parent]="parent"
            [rowActions]="rowActions"
            [cellActionEmitter]="cellActionEmitter"
            [selectedRows]="selectedRows">
    </tbody>
</table>

正如你所看到的,一切都取决于customRowComponent.

如果我不设置它,表就可以正常工作:

<tbody>
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>
</tbody>

然而,一旦我使用一些自定义行组件,html 就会变成这样:

<tbody>
    <div custom-row-selector>
        <tr>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </div>
</tbody>

这显然打破了桌子。用于呈现自定义组件的组件如下所示:

@Component({
    selector: '[crud-table-row-renderer]',
    template: '<ng-template #container></ng-template>',
})
export class RowRenderer implements OnInit, OnChanges {
    @Input() public config = new TableConfig();
    @Input() public columns: FieldConfig[];
    @Input() public rows: any[];
    @Input() public rowActions: RowAction[];
    @Input() public parent: any;
    @Input() public renderComponent: any;
    @Input() public selectedRows: number[];

    @Input() public cellActionEmitter: any;

    @ViewChild('container', {read: ViewContainerRef, static: true}) viewContainer: ViewContainerRef;

    instance: TableRowComponentInterface;

    constructor(
        @Host() public host: ElementRef,
        protected componentFactoryResolver: ComponentFactoryResolver,
    ) {
    }

    ngOnInit(): void {
        this.loadRenderer();
    }

    ngOnChanges(changes: SimpleChanges): void {
        if (changes && changes.rows && changes.rows.currentValue) {
            this.instance.rows = changes.rows.currentValue;
        }
    }

    loadRenderer() {
        const component = this.renderComponent;
        const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
        const viewContainerRef = this.viewContainer;

        const componentRef = viewContainerRef.createComponent(componentFactory);
        this.instance = componentRef.instance as TableRowComponentInterface;
        this.instance.config = this.config;
        this.instance.columns = this.columns;
        this.instance.rows = this.rows;
        this.instance.rowActions = this.rowActions;
        this.instance.parent = this.parent;
        this.instance.selectedRows = this.selectedRows;
        this.instance.cellActionEmitter = this.cellActionEmitter;
    }
}

所以最大的问题是:如何确保 Angular 不会将这个动态创建的组件包装到div or ng-component tag?


我假设你的意思是“明显打破”表格是因为它不再正确呈现ng-component在。。之间tbody and tr元素。由于您创建了自定义组件并且没有声明自定义选择器,因此角度组件将使用默认值呈现ng-component选择器。组件简单地包装在选择器中; (据我所知)这是你无法阻止的。当在 html 输出中呈现时,组件只需要包装在选择器中即可。如果您不需要选择器,则应该使用指令(属性)。

但是,通过将以下样式添加到组件中可以简单地解决正确渲染表格的问题:

:host {
  display: contents;
}

阅读更多内容display: contents 在 MDN 上 https://developer.mozilla.org/en-US/docs/Web/CSS/display#display_contents。 当浏览器以 html 形式呈现该组件时,这将完全忽略该组件,只考虑它的内容。

因此,自定义行组件的声明可能如下所示:

@Component({
  //selector: 'my-row-component',
  templateUrl: './row.component.html',
  styles: [':host { display: contents }']
}

我注释掉了选择器,但是如果取消注释,您会看到默认选择器ng-component选择器将在 html 中相应地替换为您的自定义值,但不会对渲染产生影响。

I made 这里有一个 Stackblitz https://stackblitz.com/edit/angular-qyaujp?file=src/table/row/row.component.ts来演示这个解决方案。在此 Stackblitz 中,我将上面的代码示例简化为最低限度,以简单地展示其工作原理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular 8 - 删除 ng-component 标签 - 表行模板 的相关文章

随机推荐

  • Capistrano 3 运行每个命令两次(新安装)- 配置问题

    我刚刚完成第一次 Capistrano 安装 大部分内容都保留为默认设置 我配置了我的服务器 其身份验证 远程文件夹以及对 git 存储库的访问 我使用 capistrano 将 php 代码部署到我的服务器 上限分期部署 and 上限生产
  • 从文件中读取单词并放入列表中

    本质上 我有一个巨大的文件 所有文件包含每行多个单词 每个单词用空格分隔 有点像这样 WORD WORD WORD WORD ANOTHER WORD SCRABBLE BLAH YES NO 我想要做的是将文件中的所有单词放入一个巨大的列
  • 设置区域设置和字符串模块

    这个简单的脚本 from locale import LC ALL setlocale print setlocale LC ALL from string import letters print letters 给我这个输出 tr TR
  • CSS:表达式(使用百分比或像素来计算)

    我想设置 DIV 的宽度 例如 100 10px 使用CSS表达式但一直失败有人可以告诉我答案是什么 不幸的是 你不能这样做 而且这可能会很烦人 因为你确实遇到了这样做会很棒的情况 您可以使用 Javascript 来计算元素的像素宽度 但
  • 无法初始化类 io.confluence.kafka.schemaregistry.client.rest.RestService

    我正在尝试使用 KafkaAvroSerialzer 设置一个卡夫卡生产者以获得价值 当 rit 尝试创建生产者时 我遇到了这个错误 我正在使用 confluence 5 2 1 中提供的所有罐子 java lang NoClassDefF
  • C# 按下按钮时跳出循环

    我有一个简单的 C foreach 循环 如何在按下按钮时跳出循环 它不在backgroundWorker线程中 所以我不能使用backgroundWorker Cancellation Pending 在表单中创建一个布尔标志 将事件处理
  • 在 html 中创建子页面 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 假设我有一个网站http www example com http www example com 如何为此页面创建更多子页面 即 w
  • 在lua中组合两个函数

    我刚开始学习lua 所以我的要求可能是不可能的 现在 我有一个接受函数的方法 function adjust focused window fn local win window focusedwindow local winframe w
  • 是否已经有一些基于 std::vector 的 set/map 实现?

    对于小型集合或地图 通常使用排序向量而不是基于树的向量要快得多set map 特别是对于 5 10 个元素的情况 LLVM 有一些类本着这种精神 http llvm org docs ProgrammersManual html ds se
  • 从对象中获取类型正在返回运行时类型[重复]

    这个问题在这里已经有答案了 我有一个简单的功能 public string getType object obj Type type obj getType return type FullName 如果您在运行时创建的字符串对象上使用此函
  • 在Python中随机化列表[重复]

    这个问题在这里已经有答案了 我想知道是否有一个好方法来 震动 Python 中的项目列表 例如 1 2 3 4 5 可能会被动摇 随机化 3 1 4 2 5 任何顺序都同样可能 from random import shuffle list
  • 如何从节点服务器发送 Firebase 云消息传递?

    有什么办法可以发送通知吗FCM from a node js server 我在文档中没有找到任何有关它的内容 通过 Firebase Cloud Messaging 发送消息需要调用 HTTP 端点 如发送下游消息的文档 https fi
  • Python 中 Goto 标签的替代方案?

    我知道我不能使用 Goto 我也知道 Goto 不是答案 我读过类似的问题 但我只是想不出解决我的问题的方法 所以 我正在编写一个程序 你必须在其中猜测一个数字 这是我遇到问题的部分的摘录 x random randint 0 100 I
  • 如何在 Elixir 或 Phoenix 框架中安排代码每隔几个小时运行一次?

    假设我想每 4 小时发送一堆电子邮件或重新创建站点地图或其他任何内容 我该如何在 Phoenix 或仅使用 Elixir 做到这一点 有一个简单的替代方案 不需要任何外部依赖项 defmodule MyApp Periodically do
  • 离子和电容器 - Android 启动画面响应能力

    Context 这与闪屏图像响应能力有关 根据我的研究 它之所以发生是因为缺少文档电容器文档 启动画面 https capacitorjs com docs apis splash screen Problem 当实现电容器的闪屏插件时 问
  • 在 JavaScript 中给变量字符串加上引号

    我有一个 JavaScript 变量 var text http example com 文本可以是多个链接 如何在变量字符串周围放置 例如 我希望字符串看起来像这样 http example com var text http examp
  • 遍历 globals() 字典

    我 尝试 使用globals 在我的程序中迭代所有全局变量 我就是这样做的 for k v in globals iteritems function k v 当然 这样做时 我只是创建了另外 2 个全局变量 k and v 所以我得到这个
  • 为 MoonAPNS 创建 p12 文件时卡住了

    我在创建 p12 证书时遇到一些问题 我之前创建了一个带有推送通知的应用程序 效果很好 应用程序获取用户设备 ID 并将其保存到数据库中 我已将代码添加到我的新应用程序中 并进行了与新应用程序一起使用的修改 从日志来看 它的工作方式似乎与我
  • 如何以编程方式使用 TestNG 运行 Selenium Java 测试?

    我使用 Selenium RC 和 Java 使用 TestNG 作为测试框架 我使用 Eclipse 作为 IDE 我想非常轻松地从我自己的程序中调用 TestNG 我怎样才能做到这一点 我的以下 Java 代码运行良好 Test pub
  • Angular 8 - 删除 ng-component 标签 - 表行模板

    我有一个灵活的表格组件 有两种模式 普通表 有效 自定义行模板 这不是因为角度添加