我正在尝试以编程方式显示表格:
<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相匹配... docForm
是FormGroup
,其中包含可以上传的5种不同的文档类型。docColumns
是预先设置的displayColumns。documents
是array
中的object
,用于定义行。我已经看到了类似的问题,但是我不确定我的错误是否适合这些情况... 预先感谢!
编辑---------------------- 编辑:Olipej的答案似乎无法解决我的问题,或者我无法理解错误的出处。
我进行了一次堆栈闪电重现我的数据结构和我得到的错误: https://stackblitz.com/edit/mat-table-error-example
答案 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
的属性。
尽管如果您使用的数据对象中的属性名称从未更改。您甚至不需要动态循环这些列,我真的建议您只阅读角度垫表的标准文档并测试示例代码。
我希望这可以帮助您解决问题。