javascript - PrimeNg Table 动态单元格编辑控件

标签 javascript angular primeng primeng-datatable

我关注了 PrimeNG Table

enter image description here

这是 StackBlitz demo .

所有三列都是可编辑的。 “属性名称”列始终呈现编辑中的文本框,而“属性值类型”列始终呈现下拉列表。

但对于属性值列,我想根据以下两个条件呈现文本框或下拉列表:

  1. 文本框,如果该行的“属性值类型”单元格值为字符串
  2. Dropdown 如果该行的“Property Value Type”单元格值为Boolean

我在网格 HTML 中添加了条件编辑控件。当我将“属性值类型”单元格的值从字符串更改为 bool 值(或其他方式)时,该行的“属性值”单元格应该呈现下拉列表,但它仍然显示一个文本框(除非我触发分页事件或排序事件)。

如何刷新特定单元格?

组件:

export class AppComponent {
  name = 'Angular';
  tableColumns = [
    { field: 'propName', header: 'Property Name' },
    { field: 'propValue', header: 'Property Value' },
    { field: 'propValueType', header: 'Property Value Type' },
  ];
  booleanOptions = [{ label: 'true', value: 'true' }, { label: 'false', value: 'false' }];
  propValueTypeOptions = [{ label: 'String', value: 'String' }, { label: 'Boolean', value: 'Boolean' }];
  tableItems = [
    { propName: 'prop 1', propValue: 'value 1', propValueType: 'String' },
    { propName: 'prop 2', propValue: 'true', propValueType: 'Boolean' },
    { propName: 'prop 3', propValue: 'value 3', propValueType: 'String' },
    { propName: 'prop 4', propValue: 'true', propValueType: 'Boolean' },
    { propName: 'prop 5', propValue: 'value 5', propValueType: 'String' },
    { propName: 'prop 6', propValue: 'true', propValueType: 'Boolean' },
    { propName: 'prop 7', propValue: 'value 7', propValueType: 'String' },
    { propName: 'prop 8', propValue: 'true', propValueType: 'Boolean' },
    { propName: 'prop 9', propValue: 'value 9', propValueType: 'String' },
    { propName: 'prop 10', propValue: 'true', propValueType: 'Boolean' },
  ];


  refreshGrid() {
    const temp = [...this.tableItems];
    this.tableItems = temp;
    setTimeout(() => {
      this.tableItems = [...temp];
    }, 0);
  }

  showPropNameEditCellTextBox(col) {
    return (col.field === 'propName');
  }

  showPropValueTypeEditDdl(col) {
    return (col.field === 'propValueType');
  }

  showPropValueTxtIfString(rowData, col) {
    return (col.field === 'propValue' && rowData.propValueType === 'String');
  }

  showPropValueDdlIfBoolean(rowData, col) {
    return (col.field === 'propValue' && rowData.propValueType === 'Boolean');
  }
}

HTML:

<div>
    <p-table [columns]="tableColumns" [value]="tableItems" [paginator]="true" [rows]="15" resizableColumns="true" responsive="true"
     [rowHover]="true" derableColumns="true">
        <ng-template pTemplate="header" let-columns>
            <tr>
                <th *ngFor="let col of columns" [pSortableColumn]="col.field">
                    {{col.header}}
                    <p-sortIcon [field]="col.field"></p-sortIcon>
                </th>
            </tr>
        </ng-template>
        <ng-template pTemplate="body" let-rowData let-columns="columns">
            <tr>
                <td pEditableColumn *ngFor="let col of columns">
                    <p-cellEditor>
                        <ng-template pTemplate="output">
                            {{rowData[col.field]}}
                        </ng-template>

            <!-- Show text box for "Property Name" column -->
                        <ng-template pTemplate="input" *ngIf="showPropNameEditCellTextBox(col)">
                            <input pInputText [(ngModel)]="rowData[col.field]" type="text" maxlength="50" class="form-control" />
            </ng-template>
            <!-- Show text box for "Property Name" column /-->

            <!-- Show Text for "Property Value" column if Property Value Type column is "String" -->
            <ng-template pTemplate="input" *ngIf="showPropValueTxtIfString(rowData, col)">
              <input pInputText [(ngModel)]="rowData[col.field]" type="text" maxlength="50" class="form-control" />
            </ng-template>
            <!-- Show Text for "Property Value" column if Property Value Type column is "String" /-->

            <!-- Show Dropdown for "Property Value" column if Property Value Type column is "Boolean" -->
            <ng-template pTemplate="input" *ngIf="showPropValueDdlIfBoolean(rowData, col)">
              <select class="form-control" [(ngModel)]="rowData[col.field]">
                <option *ngFor="let item of booleanOptions" class="form-control" [value]="item.value">{{item.label}}</option>
              </select>            
            </ng-template>
            <!-- Show Dropdown for "Property Value" column if Property Value Type column is "Boolean" /-->

            <!-- Show dropdown for "Property Value Type" column -->
            <ng-template pTemplate="input" *ngIf="showPropValueTypeEditDdl(col)">
              <select class="form-control" [(ngModel)]="rowData[col.field]" (change)="refreshGrid()">
                <option *ngFor="let item of propValueTypeOptions" class="form-control" [value]="item.value">{{item.label}}</option>
              </select>
            </ng-template>
            <!-- Show dropdown for "Property Value Type" column /-->
                    </p-cellEditor>
                </td>
            </tr>
        </ng-template>
    </p-table>
</div>

最佳答案

PrimeNG Table 根据值变化的引用来检测变化,因此只需创建一个新对象或进行深拷贝就可以解决您的问题

要进行深度复制,请使用 JSON.parse(JSON.stringify(a)) 或使用 cloneDeep来自 lodash

refreshGrid() {
    let temp = [...this.tableItems];
    temp = JSON.parse(JSON.stringify(temp));
    this.tableItems = temp;
    setTimeout(() => {
      this.tableItems = [...temp];
    }, 0);
}

已更新 stackblitz

关于javascript - PrimeNg Table 动态单元格编辑控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54249026/

相关文章:

javascript - jQuery加载动画hide()、show()错误

angular - 如何将 *ngIf 值从一个组件传递到另一个组件?

javascript - 如何仅在可用时使用提供商发送的数据?

angular - 使用primeng日历时如何格式化日期?

javascript - 使用 setValue angular 4 时,错误在位置 0 处缺少数字

javascript - 如何添加到现有的 JSON.stringify 字符串

.net - 从服务器端应用程序向客户端推送消息?

javascript - 使用 JavaScript 将值从 HTML 传递到 XSLT

angular - 如何通过符号链接(symbolic link)或存储库导出和集成独立的 Angular 模块?

angular - 如何在 primeng 数据表上设置默认排序顺序?