首页 > 解决方案 > 通过 UI 对模型的更改不会反映在反应式表单的表单值中

问题描述

我正在使用反应式表单,我有一个文本框,表单中的其他项目是 matrix ,它基本上是对象数组。

表单的初始化是使用以下代码完成的:

initilazieForm(): void {
    this.specForm = this.fb.group({
      name: 'Enter specsheet name',
      matrix: this.fb.array(this.mat, [Validators.required])
    });
  } 

this.mat 如下

createBaseMatrix(): MatrixDTO[] {
    this.mat[this.mat.length] = new MatrixDTO();
    this.mat[0].name = 'Basic Weight(lbs/3000ft)';
    this.mat[0].customRow = false;
    this.mat[0].items.push({ label: '30', customCol: false });
    this.mat[0].items.push({ label: '35', customCol: false });
    this.mat[0].items.push({ label: '40', customCol: false });

    this.mat[this.mat.length] = new MatrixDTO();
    this.mat[1] = new MatrixDTO();
    this.mat[1].name = 'Basic Weight(g/m2)';
    this.mat[1].customRow = false;
    this.mat[1].items.push({ label: '34', customCol: false });
    this.mat[1].items.push({ label: '42', customCol: false });
    this.mat[1].items.push({ label: '68', customCol: false });

    return this.mat;
  }

我在同一个表单上有两个按钮,用于插入自定义行或列(文本框),以便用户输入值。

但是当我添加自定义行和列时,将数据插入到每一行或每一列的文本框中,并提交这些值并没有反映在this.mat表单值中的表单

addRow() {
    console.log('add row clicked');
    this.mat[this.mat.length] = new MatrixDTO();
    this.mat[this.mat.length - 1].name = '';
    this.mat[this.mat.length - 1].customRow = true;
    let colsCount: number = this.mat[0].items.length;
    var i;
    for (i = 0; i < colsCount; i++) {
      this.mat[this.mat.length - 1].items.push({ label: '', customCol: true });
    }
    console.log(this.mat);
  }
  addColumn() {
    this.mat.forEach(x => x.items.push({ label: '', customCol: true }));
    console.log('add column clicked');
    console.log(this.mat);
  } 



<form [formGroup]="specForm" (ngSubmit)="submitForm()">
  <div class="container">
    <div class="row">
      <div class="col-9">
        <label for="name">Enter specsheet name</label>
        <input type="text" class="form-control" placeholder="Enter specsheet name" formControlName="name" id="name">

      </div>
      <div class="col-3">
        <button class="btn btn-primary" type="submit">Save</button>
      </div>
    </div>
    <div class="row">
      <div class="col-6">
        <a (click)="addRow()">Insert Custom
          Row</a>
      </div>
      <div class="col-6">
        <a (click)="addColumn()">Insert
          Custom Column</a>
      </div>
    </div>

    <div class="row">
      <div class="col-12">
        <div *ngFor="let row of mat" class="row">
          <div class="col-3">
            <span *ngIf="row.customRow===false">{{row.name}}</span>
            <input *ngIf="row.customRow==true"
                                        type="text" [value]="row.name">
          </div>
          <div *ngFor="let cols of row.items" class="col-1">
            <span *ngIf="cols.customCol===false"
                                        style="padding: 5px;">{{cols.label}}</span>
            <input *ngIf="cols.customCol===true"
                                        type="text" [value]="cols.label"
                                        class="numtext">
          </div>
        </div>
      </div>
    </div>
  </div>
</form>

StackBLitz

标签: angular

解决方案


如果您想保留表单逻辑,我建议您为矩阵表示创建自定义控件并使用 ControlValueAccessor。在新组件中,您可以通过 ngModel 管理数据并将结果返回给父表单。例子。
PS:优化代码示例还有很大的空间,它被快速显示逻辑,而不是最终的干净解决方案。干杯。


推荐阅读