我有一个可编辑的 PrimeNG 表,与反应式表单(而不是 ngtemplate)绑定。如果我单击单行的编辑,所有行都会变成编辑模式。这是解释我的问题的图片。
问题在于与 PrimeNg Edit 表一起使用的 dataKey。当使用反应式表单时,我不知道要与 dataKey 绑定什么。
这是解释问题的最小代码。
HTML.ts
<div class="card">
<div class="card-header">
<h5>Reactive Forms with PrimeNg Table</h5>
</div>
<div class="card-body">
<form [formGroup]="employeeForm">
<p-table [value]="tableRowArray.controls" [responsive]="true" dataKey="name" editMode="row"
responsiveLayout="scroll" dataKey="name"> <!--dataKey is set wrongly-->
<ng-template pTemplate="header">
<tr>
<ng-container *ngFor="let col of columns">
<td>{{col}}</td>
</ng-container>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex" let-editing="editing">
<ng-container formArrayName="tableRowArray">
<tr [formGroupName]="rowIndex" [pEditableRow]="rowData">
<td style="text-align:center">
<button *ngIf="!editing" pButton pRipple type="button" pInitEditableRow icon="pi pi-pencil" class="p-button-rounded p-button-text"></button>
<button *ngIf="editing" pButton pRipple type="button" pSaveEditableRow icon="pi pi-check" class="p-button-rounded p-button-text p-button-success mr-2"></button>
<button *ngIf="editing" pButton pRipple type="button" pCancelEditableRow icon="pi pi-times" class="p-button-rounded p-button-text p-button-danger"></button>
</td>
<td>
<p-cellEditor>
<ng-template pTemplate="input"></ng-template>
<ng-template pTemplate="output">
<input type="text" class="form-control form-control-sm"
formControlName="name" />
<div class="text-danger"
*ngIf="rowData.get('name').errors && (rowData.get('name').dirty || rowData.get('name').touched)">
<div *ngIf="rowData.get('name').errors?.required">Name is Required</div>
</div>
</ng-template>
</p-cellEditor>
</td>
</tr>
</ng-container>
</ng-template>
</p-table>
</form>
</div>
<div class="card-footer">
<button type="button" class="btn btn-primary btn-sm pull-left" (click)="addNewRow()">Add Row</button>
<button type="button" class="btn btn-success btn-sm pull-right" title="Save">Save</button>
</div>
</div>
组件.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormArray, FormControl, Validators } from '@angular/forms';
@Component({
selector: 'app-add-employee',
templateUrl: './add-employee.component.html'
})
export class AddEmployeeComponent implements OnInit {
employeeForm: FormGroup;
columns: string[];
constructor(private formBuilder: FormBuilder) {
this.columns = ["Edit", "Name"];
}
ngOnInit(): void {
this.createForm();
}
get tableRowArray(): FormArray {
debugger;
return this.employeeForm.get('tableRowArray') as FormArray;
}
addNewRow(): void {
this.tableRowArray.push(this.createTableRow());
}
onDeleteRow(rowIndex:number): void {
this.tableRowArray.removeAt(rowIndex);
}
/**
* Initializes the Form & by default adds an empty row to the PRIMENG TABLE
*/
private createForm(): void {
this.employeeForm = this.formBuilder.group({
tableRowArray: this.formBuilder.array([
this.createTableRow()
])
});
}
/**
* Returns the FormGroup as a Table Row
*/
private createTableRow(): FormGroup {
return this.formBuilder.group({
name: new FormControl(null, { validators: [Validators.required, Validators.minLength(3), Validators.maxLength(50)] })
});
}
}
您在 p-table 标签中设置了两次 dataKey。除此之外,我认为您应该为行数据分配一个 ID,以便您可以将其用作 dataKey。我认为无论如何你都需要它来保存行数据。
为了解决只编辑一行时所有行都进入编辑模式的问题,需要确保表中的每一行都有一个唯一的标识符,dataKey可以使用该标识符来区分它们。以下是修改代码以包含唯一标识符的方法:
组件.html
<div class="card">
<div class="card-header">
<h5>Reactive Forms with PrimeNg Table</h5>
</div>
<div class="card-body">
<form [formGroup]="employeeForm">
<p-table [value]="tableRowArray.controls" [responsive]="true" dataKey="value.id" editMode="row"
responsiveLayout="scroll"> <!-- here i choose 'id' attribute as the unique identifier ... if your unique identifier is 'xyz', write dataKey="value.xyz" -->
<ng-template pTemplate="header">
<tr>
<ng-container *ngFor="let col of columns">
<td>{{col}}</td>
</ng-container>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex" let-editing="editing">
<ng-container formArrayName="tableRowArray">
<tr [formGroupName]="rowIndex" [pEditableRow]="rowData">
<td style="text-align:center">
<button *ngIf="!editing" pButton pRipple type="button" pInitEditableRow icon="pi pi-pencil" class="p-button-rounded p-button-text"></button>
<button *ngIf="editing" pButton pRipple type="button" pSaveEditableRow icon="pi pi-check" class="p-button-rounded p-button-text p-button-success mr-2"></button>
<button *ngIf="editing" pButton pRipple type="button" pCancelEditableRow icon="pi pi-times" class="p-button-rounded p-button-text p-button-danger"></button>
</td>
<td>
<p-cellEditor>
<ng-template pTemplate="input"></ng-template>
<ng-template pTemplate="output">
<input type="text" class="form-control form-control-sm"
formControlName="name" />
<div class="text-danger"
*ngIf="rowData.get('name').errors && (rowData.get('name').dirty || rowData.get('name').touched)">
<div *ngIf="rowData.get('name').errors?.required">Name is Required</div>
</div>
</ng-template>
</p-cellEditor>
</td>
</tr>
</ng-container>
</ng-template>
</p-table>
</form>
</div>
<div class="card-footer">
<button type="button" class="btn btn-primary btn-sm pull-left" (click)="addNewRow()">Add Row</button>
<button type="button" class="btn btn-success btn-sm pull-right" title="Save">Save</button>
</div>
</div>
组件.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormArray, FormControl, Validators } from '@angular/forms';
@Component({
selector: 'app-add-employee',
templateUrl: './add-employee.component.html'
})
export class AddEmployeeComponent implements OnInit {
employeeForm: FormGroup;
columns: string[];
id: number = 0;
constructor(private formBuilder: FormBuilder) {
this.columns = ["Edit", "Name"];
}
ngOnInit(): void {
this.createForm();
}
get tableRowArray(): FormArray {
debugger;
return this.employeeForm.get('tableRowArray') as FormArray;
}
addNewRow(): void {
this.tableRowArray.push(this.createTableRow());
}
onDeleteRow(rowIndex:number): void {
this.tableRowArray.removeAt(rowIndex);
}
/**
* Initializes the Form & by default adds an empty row to the PRIMENG TABLE
*/
private createForm(): void {
this.employeeForm = this.formBuilder.group({
tableRowArray: this.formBuilder.array([
id: [this.id++],
// add other form attributes...
])
});
}