如何在模板中以角色形式访问动态的输入名称属性

发布于 2025-02-02 10:48:02 字数 1618 浏览 2 评论 0原文

我将 ngx-datatable包装在form> 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>

I wrapped an ngx-datatable component in a form tag so I can validate inputs in the table cells. Due to the nature of how the table is populated I set the inputs name properties dynamically

<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.

<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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨轻弹 2025-02-09 10:48:02

您可以将输入包装到新组件中,并且可以通过@viewchildren(...)访问这些生成的组件 in Parent Components .ts file> File:

@ViewChildren(NgxDatatableInput) datatableInputs: QueryList<NgxDatatableInput>;

我建议在中创建方法父组件,从datatableInputs by name作为参数中检索混凝土datatableInput。之后,您可以在生成的,新的验证pancomponent中使用此方法:


<ValidationSpan [control]="getDatatableInput(dynamicName)">
</ValidationSpan>

verialationspancomponent的模板

<span *ngIf="!control.valid && 
      !control.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:

@ViewChildren(NgxDatatableInput) datatableInputs: QueryList<NgxDatatableInput>;

I recommend to create method in parent component, which retrieves concrete datatableInput from datatableInputs by name as parameter. After that you can use this method in generated, new ValidationSpanComponent:


<ValidationSpan [control]="getDatatableInput(dynamicName)">
</ValidationSpan>

Template of ValidationSpanComponent:

<span *ngIf="!control.valid && 
      !control.pristine"
      class="[ c-validation-message ]">
  required
</span>
孤城病女 2025-02-09 10:48:02

灵感来自这个答案我想出了以下解决方案

<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: { [columnId: string]: boolean},
    changed: { [columnId: 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"
/>

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: { [columnId: string]: boolean},
    changed: { [columnId: 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"
/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文