[英]How to access dynamically set inputs name property in an Angular form in the template
我將一個ngx-datatable組件包裝在一個form
標簽中,這樣我就可以驗證表格單元格中的inputs
。 由於表格填充方式的性質,我動態設置輸入name
屬性
<form #tableForm="ngForm">
<ngx-datatable
[rows]="_rows">
<ng-container *ngFor="let column of rowDeffinition; let columnIndex=index">
<ngx-datatable-column [prop]="column.key" [name]="column.label">
<ng-template ngx-datatable-cell-template let-rowIndex="rowIndex" let-value="value" let-row="row">
<input
class="cell-input"
(blur)="updateCellValue($event, column.key, rowIndex)"
type="text"
[ngModel]="value"
[name]="rowIndex + '-' + column.key"
/>
...
</ng-template>
</ngx-datatable-column>
</ng-container>
</ngx-datatable>
</form>
通常, name
屬性會在模板中創建一個局部變量,您可以通過變量名訪問輸入控件屬性。
<input type="text" name="name" [(ngModel)]="name" required minlength="4" />
<div *ngIf="name.invalid && name.touched">
我想知道如何以與設置輸入名稱相同的方式動態地執行此操作。 到目前為止,我能夠通過表單引用訪問輸入控件,但這變得非常羅嗦
<span *ngIf="!tableForm.controls[rowIndex + '-' + column.key]?.valid &&
!tableForm.controls[rowIndex + '-' + column.key]?.pristine"
class="[ c-validation-message ]">
required
</span>
您可以將輸入包裝在新組件中,並且可以通過父組件.ts
文件中的@ViewChildren(...)
訪問這些生成的組件:
@ViewChildren(NgxDatatableInput) datatableInputs: QueryList<NgxDatatableInput>;
我建議在父組件中創建方法,該方法通過name
作為參數從datatableInputs
中檢索具體的 datatableInput。 之后,您可以在生成的新ValidationSpanComponent
中使用此方法:
<ValidationSpan [control]="getDatatableInput(dynamicName)">
</ValidationSpan>
ValidationSpanComponent
的模板:
<span *ngIf="!control.valid &&
!control.pristine"
class="[ c-validation-message ]">
required
</span>
受這個答案的啟發,我想出了以下解決方案
<form #tableForm="ngForm">
<ngx-datatable
[rows]="_rows">
<ng-container *ngFor="let column of rowDeffinition; let columnIndex=index">
<ngx-datatable-column [prop]="column.key" [name]="column.label">
<ng-template ngx-datatable-cell-template let-rowIndex="rowIndex" let-value="value" let-row="row">
<!-- Helper template allowing to define few variables for more readable property binding-->
<ng-template #cellContent [ngTemplateOutlet]="cellContent"
let-cellName="cellName" let-isValidInput="isValidInput" let-isPristineInput="isPristineInput"
let-isRequiredInput="isRequiredInput"
[ngTemplateOutletContext]="{
cellName: rowIndex + '-' + column.key,
isValidInput: tableForm.controls[rowIndex + '-' + column.key]?.valid,
isPristineInput: tableForm.controls[rowIndex + '-' + column.key]?.pristine,
isRequiredInput: column.input?.required
}">
<input
class="cell-input"
(blur)="updateCellValue($event, column.key, rowIndex)"
type="text"
[ngModel]="value"
[name]="cellname"
/>
...
</ng-template>
</ng-template>
</ngx-datatable-column>
</ng-container>
</ngx-datatable>
</form>
這極大地提高了一般的可讀性,因為我的表具有非常復雜的邏輯,並且我以如下結構跟蹤單元格的狀態:
interface EditTableRowStatus {
editing: { [coolumnId: string]: boolean},
changed: { [coolumnId: string]: boolean},
addedRow: boolean;
}
let rowsStates = EditTableRowStatus[]
這導致模板中的屬性綁定超級復雜
<input
class="cell-input"
*ngIf="column.input?.type === INPUT_TYPES.TEXT && (rowsStates[rowIndex]?.editing?.[column.key] || rowsStates[rowIndex]?.addedRow)"
[autofocus]="!rowsStates[rowIndex]?.addedRow || columnIndex === 0 "
(blur)="updateCellValue($event, column.key, rowIndex)"
type="text"
[ngModel]="value"
[ngClass]="{'has-changes': rowsStates[rowIndex]?.changed?.[column.key]}"
[name]="rowIndex + '-' + column.key"
[required]="column.input?.required"
/>
現在變得更具可讀性
<input
class="cell-input"
*ngIf="inputType === INPUT_TYPES.TEXT && (isEditing || isAddedRow)"
[autofocus]="!isAddedRow || columnIndex === 0 "
(blur)="updateCellValue($event, column.key, rowIndex)"
type="text"
[ngModel]="value"
[ngClass]="{'has-changes': isChanged}"
[name]="cellName"
[required]="isRequiredInput"
/>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.