检索 firebase 列表数据以创建动态 table

Retrieve firebase list data to create a dynamic table

当我从 firebase 数据库检索值时,我想将值推送到如下数组中

 columns: any[];
 this.columns = [
{ columnDef: 'FirstName', header: 'First Name',    cell: (element: any) => `${element.FirstName}` },
{ columnDef: 'LastName', header: 'Last Name',    cell: (element: any) => `${element.LastName}` },
];

这是我到目前为止尝试过的......

 this.af.list('/datalist', {
 query: {
    limitToLast: 200,
    orderByChild: 'name',
    equalTo: 'spiderman',
    preserveSnapshot: true
  }
 }).subscribe(snapshot=>{
   if(snapshot!=undefined){
    snapshot.forEach(function(childSnapshot) {

    this.columns.push( { columnDef: childSnapshot.heroname, header: childSnapshot.herotitle,    cell: (element: any) => `${element.heroname}` });
    this.displayedColumns = this.columns.map(c => c.columnDef);

    return false;
    });
   }
  });

上面代码的错误是 无法读取未定义

的 属性 'columns'

尽管我全局声明了列数组,但它无法识别它。

在HTML中我想这样使用....

   <ng-container *ngFor="let column of columns" [cdkColumnDef]="column.columnDef">
    <mat-header-cell *cdkHeaderCellDef>{{ column.header }}</mat-header-cell>
    <mat-cell *cdkCellDef="let row">{{ column.cell(row) }}</mat-cell>
   </ng-container>

如有任何提示,我们将不胜感激。谢谢。

您收到此错误是因为以下代码:

snapshot.forEach(function(childSnapshot) {

this.columns.push( { columnDef: childSnapshot.heroname, header:  childSnapshot.herotitle,    cell: (element: any) => `${element.heroname}` });
this.displayedColumns = this.columns.map(c => c.columnDef);

return false;
});

此处 forEach 将回调函数作为第一个参数,而回调中的 this 处于不同的上下文中,因此您会收到该错误。

要解决这个问题,你需要使用arrow function:

An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this which is not present in current scope they end up finding this from its enclosing scope.

基本上箭头函数中的 this 将引用定义箭头函数的 this 的含义,因此您将能够执行以下操作:

snaphot.forEach((childSnapshot)=>{

this.columns.push( { columnDef: childSnapshot.heroname, header: childSnapshot.herotitle,    cell: (element: any) => `${element.heroname}` })
this.displayedColumns = this.columns.map(c => c.columnDef);

return false;
});