关于rxjs:angular材质表未显示数据

Angular material table not showing data

想要在客户端进行分页和排序的人,请参考此链接

这是我尝试过的。数据正在控制台中加载。但它不会显示在网格或席子表上。

控制台中没有任何错误。我可以在控制台中看到数据,但是数据没有加载到网格中。

有人可以告诉我我在做什么错吗?

从中发出数据的实际数据库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
export class FormsDatabase {

   formsList =  new BehaviorSubject([]);
    get data(){

      return this.formsList.value;
   }

 constructor(private _formsServicedata: FormsService){
    this._formsServicedata.getAllFormData('').subscribe((form)=>{
        console.log("Form DataSource:");
    this.formsList.next(form);
  })
   }

}


export class FormDataSource extends DataSource{

    constructor( private formsDb: FormsDatabase,public
    paginator:MatPaginator , public sort: MatSort
    ) {
       super()        
      }

   connect():Observable{
      const formsData=[
         this.formsDb.formsList ,
         this.sort.sortChange
    ];

     return Observable.merge(...formsData).map(()=>{
          this.getSortedData();
    })


    }

排序功能以对数据进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
      getSortedData(){

        const data = this.formsDb.data.slice();
       if(!this.sort.active || this.sort.direction==''){ return data;}

        return data.sort((a,b)=>{

        let propertyA:number|string='';
        let propertyB:number|string='';

    switch(this.sort.active)
    {
        case 'formname': [propertyA,propertyB]=
     [a.formname,b.formname];break;
        case 'displaytext': [propertyA,propertyB]=
     [a.displaytext,b.displaytext];break;
        case 'sortorder': [propertyA,propertyB]=
     [a.sortorder,b.sortorder];break;
    }

    let valueA = isNaN(+propertyA) ? propertyA : +propertyA;
    let valueB = isNaN(+propertyB) ? propertyB : +propertyB;

    return (valueA < valueB?-1:1)*(this.sort.direction=='asc'?1:-1);
   });
  }

       disconnect() { }

 }

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  <mat-table #table [dataSource]="dataSource" matSort>

      <ng-container matColumnDef="formname">
        <mat-header-cell *matHeaderCellDef mat-sort-header> FORM NAME
     </mat-header-cell>
          <mat-cell *matCellDef="let element"> {{element.formname}}
    </mat-cell>
      </ng-container>


      <ng-container matColumnDef="displaytext">
        <mat-header-cell *matHeaderCellDef mat-sort-header> DISPLAY TEXT </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.displaytext}} </mat-cell>
      </ng-container>

      <ng-container matColumnDef="sortorder">
            <mat-header-cell *matHeaderCellDef mat-sort-header> SORT ORDER</mat-header-cell>
            <mat-cell *matCellDef="let element"> {{element.sortorder}} </mat-cell>
      </ng-container>

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

    <mat-paginator #paginator
                   [pageSize]="10"
                   [pageSizeOptions]="[5, 10, 20]"
                   [showFirstLastButtons]="true">
    </mat-paginator>

服务:

Forms Service具有以下方法,该方法以可观察的形式返回表单列表

1
2
3
  getAllFormData(orderBy:string) {
    return this.af.list('/forms');
  }


我重现了您的代码,就像您不能像angular材质团队提供的示例那样使它工作,但是我使用了一种变通方法来使sort函数起作用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 export class FormDataSource extends DataSource {

      constructor(private formsDb: FormsDatabase, public paginator: MatPaginator,
        public sort: MatSort) {
        super();
        this.sort.sortChange.subscribe(t =>
          this.formsDb.formsList.next(this.getSortedData()));
      }

      connect(): Observable {
        return this.formsDb.formsList;
      }
        getSortedData () {
          const data = this.formsDb.data.slice();
          if (!this.sort.active || this.sort.direction === '') {
            return data;
          }
          return data.sort((a, b) => {

            let propertyA: number | string = '';
            let propertyB: number | string = '';

            switch (this.sort.active) {
              case 'formname':
                [propertyA, propertyB] =
                  [a.formname, b.formname];
                break;
              case 'displaytext':
                [propertyA, propertyB] =
                  [a.displaytext, b.displaytext];
                break;
              case 'sortorder':
                [propertyA, propertyB] =
                  [a.sortorder, b.sortorder];
                break;
            }

            const valueA = isNaN(+propertyA) ? propertyA : +propertyA;
            const valueB = isNaN(+propertyB) ? propertyB : +propertyB;

            return (valueA < valueB ? -1 : 1) * (this.sort.direction == 'asc' ? 1 : -1);
          });
        }

        disconnect() {
        }
      }

查看init后

enter


<mat-table>标记中添加ngIf="dataSource"

如果数据是异步的,则会出现此问题。

会在获取数据之前加载DOM。

在呈现DOM之前检查dataSource


来自示例https://material.angular.io/components/table/overview
您应该从中删除tr元素。
错误的实现:

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

正确的实现:

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


由于angular检测变化的方式而发生此问题,有时这种情况不会发生,也不会触发重新渲染。

要解决此问题,请从'@angular/core'导入ChangeDetectorRef,将其注入组件constructor (cd: ChangeDetectorRef)中,然后在对数据进行排序后使用它:

1
2
3
4
return Observable.merge(...formsData).map(()=>{
  this.getSortedData();
  this.cd.detectChanges(); // or this.cd.markForCheck() if detectChanges does not work.
})