Angular: 共享 Table 组件添加从父组件传递的内联按钮

Angular: A Shared Table Component adding inline buttons passed from Parent Component

我被卡住了,但很确定我在做什么是可能的。

场景: 我制作了一个 common-table.component.ts,其中包含一个 mat-table (Angular Material Table) 来显示数据。
现在 我需要以一种非常generic/dynamic 的方式从父级向它添加按钮(带有事件)。子组件将需要更新按钮上的属性或参数以使其特定于该行。

场景示例:

  1. 具有 table 用户的“用户”页面(其中 table 是子组件。)
  2. 现在我们要添加内联按钮来执行自定义操作,例如 (edit/go-to-details/remove)。
  3. 随着行的呈现,每个按钮都针对该行进行了自定义
    模板-Html:
  4. 这是上面的一个简单例子
    https://stackblitz.com/edit/angular-datatable-responsive-mhbdfn?file=src%2Fapp%2Fviews%2Fshared-table%2Fshared-table.component.html

目前的想法涉及传递
CustomElement 有一个字符串 html-模板,其中包含要匹配的事件
或使用 Renderer2-Element 更改 DOM?

Renderer2 示例。
https://stackblitz.com/edit/angular-gnyd4e?file=src%2Fapp%2Fapp.component.ts

另一种方法是提供 ID,并在父级中使用 addEventListener()

但我愿意听取有关执行此操作的最佳方法的建议或想法吗?

您可以像这样在每一行添加一个按钮菜单

查看示例HERE

好吧,我终于想出了一个方法让它工作,但仍然对其他人如何做感兴趣。

总结: 在父组件中有一个包含列信息的对象,我用 'button' 部分扩展了它,并包含了我要执行的对象的名称和父对象本身。单独设置该方法会起作用,但如果您使用任何其他私有方法或传入模块,则会引发错误。在 HTML 中,我添加了一个新的输出方法,但将其设置为 '$event' 而不是方法(这是我缺少的部分) 在子组件中,我为将要触发的事件创建了一个新的输出对象。然后在我的 HTML 中,我在检查按钮对象的同时遍历并构建我的单元格。如果有一个按钮,我制作它并设置点击事件以发出输出并动态设置我想要执行的方法

父组件

HTML

<shared-table [dataSource]="dataSource" [columnsdef]="columns" (parentMethod)="$event"></shared-table>    

打字稿:

public dataSource = new MatTableDataSource <SampleTable>(); 
 public columns: IColumn[] = [
        { id: 'title', label: 'Title'},
        { id: 'id', label: 'Id'},
        {
            id: 'testing',
            button: {
                id: "button1",
                buttonText: "showAlertMessage",
                clickMethodName: "alertMe",
                parentClassObject: this
            }
        }
       ]

子组件
*请注意我正在跳过与答案无关的代码。

HTML(在Angular MaterialTable内)

<ng-container [matColumnDef]="column.id" *ngFor="let column of allColumns">
    <th mat-header-cell *matHeaderCellDef [fxFlex]="column.width + 'px'" mat-sort-header [ngClass]="!column.visible ? 'sr-only' : null">
            {{ column.label }}
        </th>
        <td mat-cell *matCellDef="let row" [fxFlex]="column.width + 'px'" [ngClass]="!column.visible ? 'sr-only' : null">
            <ng-container *ngIf="!column.button">
                {{ row[column.id] }}
            </ng-container>
            <ng-container *ngIf="column.button">
                <button (click)="parentMethod.emit(column.button.parentClassObject[column.button.clickMethodName](row))">
                    <span>{{column.button.buttonText}}</span>
                </button>
            </ng-container>
        </td>
    </ng-container>

TypeScript

@Input() dataSource: MatTableDataSource<any>;
@Input() columnsdef: IColumn[];
@Output() parentMethod = new EventEmitter<any>();