Элемент управления динамическим изменением ячеек таблицы PrimeNg - PullRequest
0 голосов
/ 18 января 2019

Я подписан на Таблица PrimeNG

enter image description here

Вот демоверсия StackBlitz .

Все три столбца доступны для редактирования. Столбец «Имя свойства» всегда отображает текстовое поле при редактировании, тогда как столбец «Тип значения свойства» всегда отображает раскрывающийся список.

Но для Столбец значения свойства Я хочу отображать текстовое поле или раскрывающийся список в зависимости от следующих двух условий:

  1. Текстовое поле , если значение ячейки «Тип значения свойства» для этой строки равно Строка
  2. Раскрывающийся список , если значение ячейки «Тип значения свойства» для этой строки равно Логическое

Я добавил элементы условного редактирования в сетку HTML. Когда я изменяю значение для ячейки «Тип значения свойства» со строкового на логическое (или наоборот), ячейка «Значение свойства» для этой строки должна отображать раскрывающийся список, но в нем по-прежнему отображается текстовое поле (если я не инициирую событие разбивки на страницы или сортировку событие).

Как обновить конкретную ячейку?

Компонент:

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>

1 Ответ

0 голосов
/ 18 января 2019

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

...