首页 文章

mat-sort不能在mat-table上工作

提问于
浏览
2

我的mat-table工作正常,但是在官方api文档之后添加mat-sort时,它在ngAfterViewInit中失败并显示以下消息

无法在ViewFeedbackComponent.ngAfterViewInit中设置未定义的属性'sort'

关于这个问题已经有一篇SO帖子了(参见下面的链接)Mat-table Sorting Demo not Working但我仍然无法使其正常运行 .

有人发现了这个问题吗?官方示例使用组件本身中的“静态”MatTableDataSourcedefined,但是我从后端查询 .

任何帮助是极大的赞赏!

MatSortModule已经在app.module.ts中导入,mat-sort-header指令应用于列,ngAfterViewInit已经完全像官方示例中那样...

import {  Component,  OnInit,  ViewEncapsulation,  ViewChild,  AfterViewInit} from '@angular/core';
import {  Feedback} from '../../../../../models/feedback';
import {  FeedbackService} from '../../services/feedback.service';
import {  MatTableDataSource,  MatSort} from '@angular/material';


@Component({
  selector: 'app-view-feedback',
  templateUrl: './view-feedback.component.html',
  styleUrls: ['./view-feedback.component.css'],
  encapsulation: ViewEncapsulation.Emulated
})
export class ViewFeedbackComponent implements OnInit, AfterViewInit {

  feedbacks: Feedback[] = [];
  showSpinner: boolean = true;
  displayedColumns: String[] = [
    'id',
    'user',
    'timestamp',
    'stars'
  ];
  dataSource: MatTableDataSource < Feedback > ;

  @ViewChild(MatSort) sort: MatSort;

  constructor(private _feedbackService: FeedbackService) {}

  ngOnInit() {
    this._feedbackService.getFeedback.subscribe(
      res => {
        this.feedbacks = res;
        this.dataSource = new MatTableDataSource(this.feedbacks);
      }
    );

  }

  ngAfterViewInit() {
    this.dataSource.sort = this.sort;
  }


}
<div class="mat-tbl-container mat-elevation-z8">
  <mat-table #tbl [dataSource]="dataSource" matSort>

    <!-- column definitions -->
    <ng-container matColumnDef="id">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Id</mat-header-cell>
      <mat-cell *matCellDef="let r"> {{r._id}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="user">
      <mat-header-cell *matHeaderCellDef mat-sort-header>User Id</mat-header-cell>
      <mat-cell *matCellDef="let r"> {{r.user}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="timestamp">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Date</mat-header-cell>
      <mat-cell *matCellDef="let r"> {{r.timestamp}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="stars">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Stars</mat-header-cell>
      <mat-cell *matCellDef="let r"> {{r.stars}} </mat-cell>
    </ng-container>

    <!-- tbl display settings -->
    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>

  </mat-table>

2 回答

  • 0

    问题是下一段代码

    ngAfterViewInit() {
        this.dataSource.sort = this.sort;
      }
    

    在您实际获得订阅表之前发生的事情:

    ngOnInit() {
        this._feedbackService.getFeedback.subscribe(
          res => {
            this.feedbacks = res;
            this.dataSource = new MatTableDataSource(this.feedbacks);
          }
        );
    
      }
    

    作为一种可能的解决方案,您可以通过 Observable.zip 同步 ngAfterViewInit call和 getFeedback subscription . 请参考RxJS zip documentation

  • 1

    我使用旧版角度材料中的前一种排序方法示例 . 最新的角度材质排序示例使用 ngAfterViewInit() 来调用sort this.dataSource.sort = this.sort; 我无法使用新示例进行排序 . 旧的排序方法使用扩展DataSource . 我能够使用来自'@angular/cdk/table'的新路径`import 导入DataSource;

    import { Component, ViewChild, Inject, OnInit, ElementRef } from '@angular/core';
    import { MatTableDataSource, MatSort } from '@angular/material';
    import { DataSource } from '@angular/cdk/table';
    import { Observable } from 'rxjs/Observable';
    import { HttpClient, HttpResponse, HttpHeaders, HttpRequest} from '@angular/common/http';
    import 'rxjs/add/operator/startWith';
    import 'rxjs/add/observable/merge';
    import 'rxjs/add/observable/of';
    import 'rxjs/add/operator/map';
    
    export interface Data {}
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    
    export class AppComponent implements OnInit {
    
      myData: Array < any > ;
      displayedColumns = ['id', 'name'];
    
      dataSource: MyDataSource;
    
      @ViewChild(MatSort) sort: MatSort;
    
      constructor(private http: HttpClient) {}
    
     getData() {
        let url = 'https://api.mydatafeeds.com/v1.1/cumulative_player_data.json?';
        let headers = new HttpHeaders({ "Authorization": "123ykiki456789123456" });
        this.http.get(url, {headers})
          .subscribe(res => {
            this.myData = res;
            this.dataSource = new MyDataSource(this.myData, this.sort);
          });
      }
    
      ngOnInit() {
        this.getData();
      }
    }
    
    export class MyDataSource extends DataSource < any > {
      constructor(private dataBase: Data[], private sort: MatSort) {
        super();
      }
      /** Connect function called by the table to retrieve one stream containing the data to render. */
      connect(): Observable < Data[] > {
        const displayDataChanges = [
          Observable.of(this.dataBase),
          this.sort.sortChange,
        ];
    
        return Observable.merge(...displayDataChanges).map(() => {
          return this.getSortedData();
        });
      }
    
      disconnect() {}
    
      /** Returns a sorted copy of the database data. */
      getSortedData(): Data[] {
        const data = this.dataBase.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 'id':
              [propertyA, propertyB] = [a.id, b.id];
              break;
            case 'name':
              [propertyA, propertyB] = [a.name, b.name];
              break;
    
          }
    
          let valueA = isNaN(+propertyA) ? propertyA : +propertyA;
          let valueB = isNaN(+propertyB) ? propertyB : +propertyB;
    
          return (valueA < valueB ? -1 : 1) * (this.sort.direction == 'asc' ? 1 : -1);
        });
    
      }
    
    }
    
    <mat-table #table [dataSource]="dataSource" matSort>
      <ng-container matColumnDef="id">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Id </mat-header-cell>
        <mat-cell *matCellDef="let data"> <b>{{data.id}}.</b>
        </mat-cell>
      </ng-container>
      <ng-container matColumnDef="name">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Id </mat-header-cell>
        <mat-cell *matCellDef="let data"> <b>{{data.name}}.</b>
        </mat-cell>
      </ng-container>
      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let data; columns: displayedColumns;"></mat-row>
    </mat-table>
    

相关问题