MatTable-角材质:找不到ID为的列

时间:2019-06-17 09:34:47

标签: angular forms angular-material mat-table

我正在尝试以编程方式显示表格:

<div [formArrayName]="doc.typeSelector">
                  {{ doc.typeSelector }}
</div>
<div *ngIf="documents[doc.typeSelector]">
     <mat-table
      [dataSource]="documents[doc.typeSelector]"
      *ngFor="let col of docColumns">
      <ng-container [matColumnDef]="col">
        <th mat-header-cell *matHeaderCellDef> {{ col | uppercase }} </th>
        <td mat-cell *matCellDef="let element"> {{ element[col] }} </td>
      </ng-container>
    <tr mat-header-row *matHeaderRowDef="docColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: docColumns;"></tr>
  </mat-table>
</div>

位置:

documents: object = {};
docColumns: string[] = ["name", "uploadDate", "uri", "comments"];
docs = [];
docForm: FormGroup;
docTypes: object = {
    fs: 'Financial Statements',
    id: 'Identity Document',
    ad: 'Bank Account Details',
    cd: 'Constitutional Document',
    pd: 'Power Document',
  };

以及在documents / docs / docFrom变量中填充ngOnInit()的位置:

[...] this.docForm = this.fb.group({});
    Object.keys(this.docTypes).map(
      type => {
        this.docForm.addControl(type, this.fb.array([]));
        this.docs.push({
         typeName: this.docTypes[type],
         typeSelector: type
        });
    }
  );

然后,如果有客户,则订阅将从数据库中获取数据... 并且一旦我们获得了信息,它就会汇总到变量中:

// Info for the docForm:
              const cusDocs = this.customer.docRefs;
              Object.keys(cusDocs).map(docType => {
                const currDocs = [];
                cusDocs[docType].forEach(doc => {
                  currDocs.push(this.customerService.createNewDoc(doc));
                });
                const matchForm = this.docForm.get(docType) as FormArray;
                currDocs.forEach(form => {
                  matchForm.push(form);
                });
              });
              Object.keys(this.docForm.value).map(docType => {
                const currForm = this.docForm.get(docType) as FormArray;
                if (currForm.value.length > 0) {
                  Object.keys(currForm.value).map(doc => {
                    const currentDoc = currForm.at(+doc).value;
                    const newDocRow = {
                      name: currentDoc.name,
                      uploadDate: currentDoc.uploadDate,
                      uri: currentDoc.uri,
                      comments: currentDoc.comment
                    };
                    if (!this.documents[docType]) {
                      this.documents[docType] = [];
                    }
                    this.documents[docType].push(newDocRow);
                    console.log(this.documents[docType]);
                  });
                }
              });
              console.log(this.documents);
              console.log(this.docColumns);
  • docs array被DOM用于显示扩展面板
  • docTypes object用于构建先前的变量,以匹配服务器的响应。可能没什么用,但是在我构建它时,我想确保服务器信息与DOM相匹配...
  • docFormFormGroup,其中包含可以上传的5种不同的文档类型。
  • docColumns是预先设置的displayColumns。
  • 最后但并非最不重要的一点,documentsarray中的object,用于定义行。

console.logs的收益如下: Logs + error

我已经看到了类似的问题,但是我不确定我的错误是否适合这些情况... 预先感谢!

编辑---------------------- 编辑:Olipej的答案似乎无法解决我的问题,或者我无法理解错误的出处。

我进行了一次堆栈闪电重现我的数据结构和我得到的错误: https://stackblitz.com/edit/mat-table-error-example

Stackblitz截图: enter image description here

3 个答案:

答案 0 :(得分:2)

您的ngFor循环在mat-table元素上设置。您想使用ng-container元素上的循环来用数据填充表。 现在,您正在生成具有错误数据的多个席子表。

更改此设置,您将看到魔术的出现:)

答案 1 :(得分:1)

您确定要传递给matTable的对象都具有与列ID匹配的属性吗?

在模板的开头,您检查“文档”中的元素,但从未检查其属性。

<div *ngIf="documents[doc.typeSelector]">

当然,您不必检查属性是否存在,但是因为出现错误:“找不到ID为“ uploadDate”的列”,我认为您传递的对象实际上还没有该属性。

如果这没有帮助,您能否提供一个堆栈闪电的示例?

答案 2 :(得分:0)

我正在创建一个新的答案,因为我需要涵盖的内容超过注释所允许的范围。

首先,您链接了一个与问题代码不匹配的stackblitz示例。既不使用mat-table,也不显示您要显示的数据。问题代码和示例代码的结构都不同。

我认为您首先需要问自己要完成的任务。然后,您需要问自己自己,解决所遇到的问题需要什么。

现在,如果您仍然认为需要使用mat-table,那么我将帮助您在动态列中使用它。

要从mat-table开始,需要显示对象数组和列ID的定义。

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
}

const ELEMENT_DATA: PeriodicElement[] = [
  {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
  {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
  {position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
  {position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
  {position: 5, name: 'Boron', weight: 10.811, symbol: 'B'},
  {position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'},
  {position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N'},
  {position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O'},
  {position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F'},
  {position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne'},
];

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = ELEMENT_DATA;
}

dataSource使用ELEMENT_DATA,它是一组对象。

displayedColumns是ID的字符串数组,是每一列的定义。请注意,此数组中的每个字符串都必须与PeriodicElement的任何属性/变量名匹配,区分大小写

这就是使用mat-table的方式。

<table mat-table [dataSource]="dataSource">
  <ng-container *ngFor="let col of displayedColumns" [matColumnDef]="col">
    <th mat-header-cell *matHeaderCellDef> {{col}} </th>
    <td mat-cell *matCellDef="let element"> {{element[col]}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

mat-table需要数据源才能显示任何内容。请注意,我将* ngFor放在哪里?我把它放在ng容器上,因为一个ng容器是一列。我遍历displayedColumns。 id数组,并使用它们获取element的属性。

Here is a working example

尽管如果您使用的数据对象中的属性名称从未更改。您甚至不需要动态循环这些列,我真的建议您只阅读角度垫表的标准文档并测试示例代码。

我希望这可以帮助您解决问题。