繁体   English   中英

如何在模板中的 Angular 表单中访问动态设置的输入名称属性

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM