带可编辑字段的角度材料表

Mic*_*xon 5 angular-material2 angular-forms angular5

我正在使用角度材料从数组形式的数据创建表格。这一切都很好。我遇到的问题是字段本身需要是表单字段。它们需要从数据中填充,但可编辑。此外,带有空白字段的新行应该是可填充和持久化的。我发现虽然行数据填充,但值永远不会进入表单字段本身,或者表单字段都只由第一条记录填充。我引用字段值的方式有问题,但我看不到它是什么。所以,这是 html 中的表格:

<form #a="ngForm" >
  <mat-table #approvalsTable [dataSource]="approvalsDataSource"
             #approvalsSort="matSort" matSort matSortActive="description"
             matSortDirection="asc" style="width:900px;font-family: Arial, Helvetica, sans-serif; font-size:14px;">

    <ng-container matColumnDef="description">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Description</mat-header-cell>
      <mat-cell *matCellDef="let element; let i = index">
        <input type="text"
               name="description" [(ngModel)]="element.description" [value]="element.description">
        {{element.description}}

      </mat-cell>
    </ng-container>

    <ng-container matColumnDef="approvalNumber">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Approval No.</mat-header-cell>
      <mat-cell *matCellDef="let element; let i = index">
        <input type="text"
               name="approvalNumber" [(ngModel)]="element.approvalNumber" [value]="element.approvalNumber">
        {{element.approvalNumber}}

      </mat-cell>
    </ng-container>

    <ng-container matColumnDef="expires">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Expiration Date</mat-header-cell>
      <mat-cell *matCellDef="let element; let i = index">
        <input type="text"
               name="expires" [(ngModel)]="element.expires" [value]="element.expires">
        {{element.expires}}

      </mat-cell>
    </ng-container>

    <ng-container matColumnDef="actions">
      <mat-header-cell *matHeaderCellDef mat-sort-header disabled>Actions</mat-header-cell>
      <mat-cell *matCellDef="let element; let i = index;" style="text-align:right;">

        <div style="min-width:9em;">
          <button (click)="addApproval(a.value)"><img src="../../assets/images/icons/plus.svg" width="20px" height="20px"/>
          </button>
          <button (click)="deleteApproval(a.value)"><img src="../../assets/images/icons/garbage.svg" width="20px" height="20px"/>
          </button>
          <button (click)="saveApproval(a.value)"><img src="../../assets/images/icons/checked-1.svg" width="20px" height="20px"/>
          </button>
        </div>

      </mat-cell>
    </ng-container>

    <mat-header-row *matHeaderRowDef="approvalsDisplayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: approvalsDisplayedColumns;"></mat-row>
  </mat-table>
</form>
Run Code Online (Sandbox Code Playgroud)

...这是填充表单和操作按钮的组件代码

  @ViewChild('approvalsSort') public approvalsSort: MatSort;

  APPROVALS_ELEMENT_DATA: Approval[] = [];
  approvalsDisplayedColumns = ['description', 'approvalNumber', 'expires', 'actions'];
  approvalsDataSource;

  ngOnInit() {
    this.currentUser = this.authenticationService.returnCurrentUser();

    // 1. Establish the organisation
    // an organisaiton may already exist, either being routed

    if (this.route.data) {
      this.route.data
        .subscribe(({ organisation }) => {
          this.organisation = organisation;
        });

    } else {
      // or is attached to the current user
      this.organisation = this.currentUser.organisation;
    }

    if (!this.organisation) {
      this.organisation = new Organisation();
    }

    // 4. Initialise the tables
    this.makeBlankApproval();

    this.render(this.organisation);    
  }

  render(o: Organisation) {
    console.log(this.organisation.approvals); // this is the console.log!!!
    this.APPROVALS_ELEMENT_DATA = o.approvals;
    this.approvalsDataSource = new MatTableDataSource<Approval>(this.APPROVALS_ELEMENT_DATA);
    this.approvalsDataSource.sort = this.approvalsSort;    
  }

  makeBlankApproval() {
    const approval: Approval = makeApproval('', '', '');
    this.organisation.approvals.push(approval);
  }

  addApproval(form: any) {
    let foundEmpty: boolean = false;
    for (let i = 0; i < this.organisation.approvals.length; i++) {
      const appToUpdate = this.organisation.approvals[i];
      if (appToUpdate.description === '' && appToUpdate.approvalNumber === '' && appToUpdate.expires === '') {
        foundEmpty = true;
      }
    }
    if (!foundEmpty) {
      this.makeBlankApproval();
    }
    this.render(this.organisation);
  }

  deleteApproval(form: any) {
    console.log(form);
  }

  saveApproval(form: any) {
    this.render(this.organisation);
  }
Run Code Online (Sandbox Code Playgroud)

现在,为了练习这个案例,我所做的是: 1. 用一些虚拟数据填充第一行 2. 保存它(使用 saveApproval(form)) 3. 添加一个新行,使用 addApproval()

我期望的是表格中的两行,第一行是空白的,第二行是填充了保存的字段数据。

我得到的是两个空白字段。

控制台日志提供了一个有趣的故事,所以这里是测试的结果:

  1. 初始表单加载: 在此处输入图片说明 在此处输入图片说明

填写并点击 saveApproval 在此处输入图片说明 在此处输入图片说明

点击添加批准 在此处输入图片说明 在此处输入图片说明

因此,如您所见,dataSource 看起来不错,操作看起来不错,元素字段是正确的(您可以在输出中看到它们),只是表单字段本身没有填充数据。也可能是所有行都填充了第 0 行的数据 - 我不确定。

作为一个有趣的附加观察:开发工具中的元素视图显示了这一点:

第二行描述元素的图片(1)

ng-reflect-model 中有值,但在这个视图中没有 value 属性存在,但它是通过 [value] 指令指定的,或者我是这么认为的。我也尝试过 ng-value 和普通的旧值属性。

那么,如何将正确的值输入到正确行的正确表单输入中?