如何用 Angular 形式创建 editable primeNG table?

How to create the editable primeNG table with Angular forms?

我正在尝试使用 angular 表单创建 PrimeNg editable table。

app.component.ts(这是最小的可重现代码)

export class AppComponent implements OnInit {
    epForm: FormGroup;
    range: FormArray;

    constructor(private fb: FormBuilder,){
    }
    ngOnInit() {
        this.epForm = new FormGroup({});
        this.epForm.addControl('range', new FormArray([]));
        this.range = <FormArray>this.epForm.get('range');
        this.range.push(
        this.fb.group({
            type: ['X1 Gene']
        })
        );
    }
}

并且 html 文件是

<form [formGroup]="epForm" novalidate>
    <p-table [value]="epForm.controls.range.value" [rows]="10" [responsive]="true">
        <ng-template pTemplate="header">
            <tr> Range </tr>
        </ng-template>
        <ng-template pTemplate="body" let-i="rowIndex">            
            <tr [formGroupName]='i'>
                <td >
                    <input type="text" pInputText formControlName="type" />
                 </td>
             </tr>
        </ng-template>
      </p-table>
</form>

我尝试使用上面的代码显示内容,但我无法编辑输入标签。我打开检查元素并检查了它,只有 tbody 是关键更新。

我删除了 [formgroup]='i' 并在控制台中检查了它 我收到以下错误

 Cannot find control with path: 'range -> type'

我用 <table> 尝试过同样的事情,它工作正常。但是对于 p-table 我得到了这种行为?我该如何解决这个问题。

StackBlitz

就像下面的图片一样,我进入了检查元素,[formGroupName]

Use Like this as mentioned in Doc 

https://www.primefaces.org/primeng/#/table/edit

Html 
    <p-table [value]="cars">
        <ng-template pTemplate="header">
            <tr>
                <th>Vin</th>
                <th>Year</th>
                <th>Brand</th>
                <th>Color</th>
            </tr>
        </ng-template>
        <ng-template pTemplate="body" let-rowData>
            <tr>
                <td pEditableColumn>
                    <p-cellEditor>
                        <ng-template pTemplate="input">
                            <input pInputText type="text" [(ngModel)]="rowData.vin">
                        </ng-template>
                        <ng-template pTemplate="output">
                            {{rowData.vin}}
                        </ng-template>
                    </p-cellEditor>
                </td>
                <td pEditableColumn>
                    <p-cellEditor>
                        <ng-template pTemplate="input">
                            <input pInputText type="text" [(ngModel)]="rowData.year" required>
                        </ng-template>
                        <ng-template pTemplate="output">
                            {{rowData.year}}
                        </ng-template>
                    </p-cellEditor>
                </td>
                <td pEditableColumn>
                    <p-cellEditor>
                        <ng-template pTemplate="input">
                            <p-dropdown [options]="brands" [(ngModel)]="rowData.brand" [style]="{'width':'100%'}"></p-dropdown>
                        </ng-template>
                        <ng-template pTemplate="output">
                            {{rowData.brand}}
                        </ng-template>
                    </p-cellEditor>
                </td>
                <td pEditableColumn>
                    <p-cellEditor>
                        <ng-template pTemplate="input">
                            <input pInputText type="text" [(ngModel)]="rowData.color">
                        </ng-template>
                        <ng-template pTemplate="output">
                            {{rowData.color}}
                        </ng-template>
                    </p-cellEditor>
                </td>
            </tr>
        </ng-template>
    </p-table>

    <h3>Row Editing</h3>
    <p-table [value]="cars2" dataKey="vin">
        <ng-template pTemplate="header">
            <tr>
                <th>Vin</th>
                <th>Year</th>
                <th>Brand</th>
                <th>Color</th>
                <th style="width:8em"></th>
            </tr>
        </ng-template>
        <ng-template pTemplate="body" let-rowData let-editing="editing" let-ri="rowIndex">
            <tr [pEditableRow]="rowData">
                <td>
                    {{rowData.vin}}
                </td>
                <td>
                    <p-cellEditor>
                        <ng-template pTemplate="input">
                            <input pInputText type="text" [(ngModel)]="rowData.year" required>
                        </ng-template>
                        <ng-template pTemplate="output">
                            {{rowData.year}}
                        </ng-template>
                    </p-cellEditor>
                </td>
                <td>
                    <p-cellEditor>
                        <ng-template pTemplate="input">
                            <p-dropdown [options]="brands" [(ngModel)]="rowData.brand" [style]="{'width':'100%'}"></p-dropdown>
                        </ng-template>
                        <ng-template pTemplate="output">
                            {{rowData.brand}}
                        </ng-template>
                    </p-cellEditor>
                </td>
                <td>
                    <p-cellEditor>
                        <ng-template pTemplate="input">
                            <input pInputText type="text" [(ngModel)]="rowData.color">
                        </ng-template>
                        <ng-template pTemplate="output">
                            {{rowData.color}}
                        </ng-template>
                    </p-cellEditor>
                </td>
                <td style="text-align:center">
                    <button *ngIf="!editing" pButton type="button" pInitEditableRow icon="pi pi-pencil" class="ui-button-info" (click)="onRowEditInit(rowData)"></button>
                    <button *ngIf="editing" pButton type="button" pSaveEditableRow icon="pi pi-check" class="ui-button-success" style="margin-right: .5em" (click)="onRowEditSave(rowData)"></button>
                    <button *ngIf="editing" pButton type="button" pCancelEditableRow icon="pi pi-times" class="ui-button-danger" (click)="onRowEditCancel(rowData, ri)"></button>
                </td>
            </tr>
        </ng-template>
    </p-table>


Component be like .

enter code here

    export class TableEditDemo implements OnInit {

        cars1: Car[];

        cars2: Car[];

        brands: SelectItem[];

        clonedCars: { [s: string]: Car; } = {};

        constructor(private carService: CarService) { }

        ngOnInit() {
            this.carService.getCarsSmall().then(cars => this.cars1 = cars);
            this.carService.getCarsSmall().then(cars => this.cars2 = cars);

            this.brands = [
                {label: 'Audi', value: 'Audi'},
                {label: 'BMW', value: 'BMW'},
                {label: 'Fiat', value: 'Fiat'},
                {label: 'Ford', value: 'Ford'},
                {label: 'Honda', value: 'Honda'},
                {label: 'Jaguar', value: 'Jaguar'},
                {label: 'Mercedes', value: 'Mercedes'},
                {label: 'Renault', value: 'Renault'},
                {label: 'VW', value: 'VW'},
                {label: 'Volvo', value: 'Volvo'`enter code here`}
            ];
        }

        onRowEditInit(car: Car) {
            this.clonedCars[car.vin] = {...car};
        }

        onRowEditSave(car: Car) {
            if (car.year > 0) {
                delete this.clonedCars[car.vin];
                this.messageService.add({severity:'success', summary: 'Success', detail:'Car is updated'});
            }
            else {
                this.messageService.add({severity:'error', summary: 'Error', detail:'Year is required'});
            }
        }

        onRowEditCancel(car: Car, index: number) {
            this.cars2[index] = this.clonedCars[car.vin];
            delete this.clonedCars[car.vin];
        }

    }

我从 primeNg 那里得到了我自己的问题的答案 documentation

Performance Tips

When selection is enabled use dataKey to avoid deep checking when comparing objects.

Use rowTrackBy to avoid unnecessary dom operations.

Prefer lazy loading for large datasets.

所以我将 table 修改为

<p-table [value]="epForm.controls.range.value" [rows]="10" [responsive]="true"
[rowTrackBy]="trackByFn">

在组件文件中我添加了下面的方法

trackByFn(index, row) {
    return index;
}