ngx-datatable - 带有操作按钮的自定义列

Posted

技术标签:

【中文标题】ngx-datatable - 带有操作按钮的自定义列【英文标题】:ngx-datatable - custom columns with action buttons 【发布时间】:2019-10-28 16:48:12 【问题描述】:

我有一个表 (ngx-datatable),我想在其中定义一个“操作”列,然后将在其中放置按钮以进行 CRUD 操作。

创建列并放置按钮有效,但我遇到的问题是所选行及其列中的值在我的触发函数中不再被识别。

这是我的模板:

<div class="col-12">
  <ngx-datatable
    #table
    class="material"
    [rowHeight]="'auto'"
    [columns]="columns"
    [columnMode]="'force'"
    [headerHeight]="50"
    [footerHeight]="50"
    [limit]="10"
    [rows]="cars?.content"
    [selected]="selected"
    [selectionType]="'multi'">
  </ngx-datatable>
</div>

这是我的带有按钮的自定义模板:

<ng-template #buttonsTemplate let-row="row" let-value="value" let-button="column.actions">
  <button class="btn btn-transparent" (click)='onSelect($event)'><i class="rb-ic rb-ic-add-frame"></i></button>
  <button class="btn bt n-transparent" (click)='onSelect($event)><i class="rb-ic rb-ic-abort-frame"></i></button>
  <button class="btn btn-transparent" (click)='onSelect($event)><i class="rb-ic rb-ic-reset"></i></button>
  <button class="btn btn-transparent" (click)='onSelect($event)><i class="rb-ic rb-ic-agility"></i></button>
</ng-template>

我的组件(.ts 文件)的结构如下:

export class MyComponent implements OnInit, OnDestroy 
  @ViewChild('buttonsTemplate') buttonsTemplate: TemplateRef<any>;
  columns = [];

  ngOnInit() 
    this.columns = [
    prop: 'id', name: 'Id',
    prop: 'serial_number', name: 'Serial Number',
    prop: 'actions', name: 'Actions', cellTemplate: this.buttonsTemplate
    ];
  

  // This method should be called after clicking an action button
  onSelect(selected) 
    console.log('Array of selected vehicles', selected);
  

目前控制台出现此错误:

错误类型错误:无法读取属性“序列号” 未定义的

我做错了什么? official documentation 和 demo page 对我没有帮助..


来自@wentjun 的方法(不起作用:按钮在列内不可见)

模板:

<ngx-datatable-column *ngFor="let column of columns; let i = index;" name="column.name" prop="column.prop">
  <ng-template #buttonsTemplate let-row="row" let-value="value" ngx-datatable-cell-template>
    <button class="btn btn-transparent" (click)='onSelect(row)'><i class="rb-ic rb-ic-add-frame"></i></button>
  </ng-template>
</ngx-datatable-column>

组件(函数):

onSelect(selected) 
  console.log('Array of selected vehicles', selected);

【问题讨论】:

您能否发布您尝试填充的响应 json(汽车内容) 你的意思是 --> id: "5cfa46bc934b930018e66c", serial_number: "Tx2dh2" 它的结构是这样的 --> content: (9) […, …, …, …, …, …, …, …, …] 【参考方案1】:
<ng-container *ngFor='let column of columns' >
            <ngx-datatable-column *ngIf='column.name === "Actions"' name="Actions" prop="actions">
                <ng-template let-value="value" let-row="row" ngx-datatable-cell-template>
                    <span>
                        <button class='btn btn-icon icon-left'>
                            Continue
                            <i [ngClass]='row.actions.continue'></i>
                        </button>
                        <button class='btn btn-icon icon-left'>
                            Remove
                            <i [ngClass]='row.actions.delete'></i>
                        </button>
                    </span>
                </ng-template>
            </ngx-datatable-column>
            <ngx-datatable-column *ngIf='column.name !== "Actions"' name="column.name" prop="column.prop">
            </ngx-datatable-column>
        </ng-container>

OP gojun 的解决方案与 Angular 10+ 中的 ng-container 配合使用效果更好。

【讨论】:

【参考方案2】:

我正在使用ngx-datatable 库,并且我的设置与您的项目类似,因此我相信我知道您的问题出在哪里。

如果你的&lt;ng-template&gt; 没有嵌套在&lt;ngx-datatable-column&gt; 中,你应该把它放在里面。此外,在您的click 事件绑定中,您应该将row 值传递给您的onSelect() 方法,因为您正在尝试访问行数据。您还需要在 &lt;ng-template&gt; 中使用 ngx-datatable-cell-template 指令。

这是你应该做的改变:

<ngx-datatable 
[rows]="rows" 
class="material" 
[loadingIndicator]="loadingIndicator"
[columnMode]="'force'" 
[headerHeight]="50" 
[footerHeight]="50" 
[rowHeight]="'auto'"
[columns]="columns" 
[reorderable]="reorderable">

  <ngx-datatable-column *ngFor="let column of columns; let i = index;" name="column.name" prop="column.prop">
    <ng-template let-value="value" let-row="row" *ngIf="column.name==='Actions'" ngx-datatable-cell-template>
      <span>
        <button style="background-color:red;height:15px;" (click)='onSelectRed(row)'><i class="rb-ic rb-ic-add-frame"></i></button>
        <button style="background-color:blue;height:15px;" class="btn" (click)='onSelectBlue(value)'><i class="rb-ic rb-ic-add-frame"></i></button>
      </span>
    </ng-template>
  </ngx-datatable-column>
</ngx-datatable>

并且在你的component.ts上,你应该可以访问整行的数据,或者属性本身的值,这取决于你在click方法上绑定的值。

onSelectRed(row) 
  console.log(row);


onSelectBlue(value) 
  console.log(value);

我在here 上创建了一个演示。如您所见,row 和绑定属性 (id) 的值可以在行按钮本身内访问。

【讨论】:

我已经用你的方法更新了我的问题。现在按钮在列内不再可见.. 嗨,我必须道歉,因为我的解释不是很清楚。我创建了一个演示,并在我的答案的代码中添加了更多详细信息。希望它能为您解决问题。 我已经逐行复制了你的代码,我认为这可能是一些错误,但对我不起作用。我不知道如何,当我修改您的 slackblitz 代码时,完全相同。请指向一些链接,我无法在我的应用程序中执行 crud 操作。【参考方案3】:

感谢@m4limo

(我添加了自己的观察)


原评论

只需使用ng-tamplate

<ngx-datatable-column name="Actions" sortable="false" prop="id">
      <ng-template let-row="row" let-value="value" ngx-datatable-cell-template>

            <button md-icon-button (click)="blockAgents(value)">
              <i class="fa fa-ban"></i>
            </button>

            <button md-icon-button (click)="approveAgent(value)">
              <i class="fa fa-check"></i>
            </button>

      </ng-template>
</ngx-datatable-column>

value 对应于您在ngx-datatable-column 中定义的属性prop,在本例中为id


观察

您需要在ngx-datatable-column 元素的prop 属性内声明列属性名称,let-value 会将属性分配给一个变量,在这种情况下,名为“值”,它将被分配/使用在您的 ng-template 子对象中。

"value" 将使用列prop 值从您的行(列出的对象)中获取属性值。列属性名称需要与行对象的属性匹配。

注意事项

在 Angular 9.1.1 中测试(使用 Ivy) 使用@swimlane/ngx-datatable 16.0.3

GitHub 原评论here

【讨论】:

【参考方案4】:

点击时传递 row 而不是 $event

<ng-template #buttonsTemplate let-row="row" let-value="value">
  <button class="btn btn-transparent" (click)='onSelect(row)'><i class="rb-ic rb-ic-add-frame"></i></button>
  <button class="btn bt n-transparent" (click)='onSelect(row)><i class="rb-ic rb-ic-abort-frame"></i></button>
  <button class="btn btn-transparent" (click)='onSelect(row)><i class="rb-ic rb-ic-reset"></i></button>
  <button class="btn btn-transparent" (click)='onSelect(row)><i class="rb-ic rb-ic-agility"></i></button>
</ng-template>

onSelect 函数中,您将能够访问行详细信息。

onSelect(row)  
  console.log(row); 

请找到工作的demo

【讨论】:

以上是关于ngx-datatable - 带有操作按钮的自定义列的主要内容,如果未能解决你的问题,请参考以下文章

在自定义通知中添加按钮操作

使用自定义谷歌登录按钮时如何退出

带有图像和文本的 XLForm 自定义行以及操作目标 C 上的推送控制器

带有自定义项的 QTreeView

网页插入SWF视频,如何带有播放控制按钮、进度条等!

自定义通知覆盖 - 实现向下滑动以显示几个按钮