[英]How to access dynamically set inputs name property in an Angular form in the template
I wrapped an ngx-datatable component in a form
tag so I can validate inputs
in the table cells.我将一个ngx-datatable组件包装在一个form
标签中,这样我就可以验证表格单元格中的inputs
。 Due to the nature of how the table is populated I set the inputs name
properties dynamically由于表格填充方式的性质,我动态设置输入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>
Normally, the name
property would creates a local variable in the template and you can access the inputs control properties via the variable name.通常, name
属性会在模板中创建一个局部变量,您可以通过变量名访问输入控件属性。
<input type="text" name="name" [(ngModel)]="name" required minlength="4" />
<div *ngIf="name.invalid && name.touched">
I wonder how can I do this dynamically in the same manner I set the inputs name.我想知道如何以与设置输入名称相同的方式动态地执行此操作。 So far I was able to access the input controls via the form reference but this becomes quite wordy到目前为止,我能够通过表单引用访问输入控件,但这变得非常罗嗦
<span *ngIf="!tableForm.controls[rowIndex + '-' + column.key]?.valid &&
!tableForm.controls[rowIndex + '-' + column.key]?.pristine"
class="[ c-validation-message ]">
required
</span>
You can wrap your input in new component and you can access these generated components via @ViewChildren(...)
in parent components .ts
file:您可以将输入包装在新组件中,并且可以通过父组件.ts
文件中的@ViewChildren(...)
访问这些生成的组件:
@ViewChildren(NgxDatatableInput) datatableInputs: QueryList<NgxDatatableInput>;
I recommend to create method in parent component, which retrieves concrete datatableInput from datatableInputs
by name
as parameter.我建议在父组件中创建方法,该方法通过name
作为参数从datatableInputs
中检索具体的 datatableInput。 After that you can use this method in generated, new ValidationSpanComponent
:之后,您可以在生成的新ValidationSpanComponent
中使用此方法:
<ValidationSpan [control]="getDatatableInput(dynamicName)">
</ValidationSpan>
Template of ValidationSpanComponent
: ValidationSpanComponent
的模板:
<span *ngIf="!control.valid &&
!control.pristine"
class="[ c-validation-message ]">
required
</span>
Inspired by this answer I came up with following solution受这个答案的启发,我想出了以下解决方案
<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>
This improves the general readability vastly, since my table has a very complex logic, and i track the state of the cell in a structure like:这极大地提高了一般的可读性,因为我的表具有非常复杂的逻辑,并且我以如下结构跟踪单元格的状态:
interface EditTableRowStatus {
editing: { [coolumnId: string]: boolean},
changed: { [coolumnId: string]: boolean},
addedRow: boolean;
}
let rowsStates = EditTableRowStatus[]
which led to super complex property binding in the template这导致模板中的属性绑定超级复杂
<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"
/>
now becoming much more readable现在变得更具可读性
<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.