角度matSort不工作

Vin*_*rih 17 angular-material angular

我将matSort导入matTable时遇到问题.

我正在为您提供我的代码:

dashboard.component.ts

import {Component, ViewChild} from '@angular/core';
import {UserService} from "../user.service";
import {DohvatMantisaService} from "../dohvat-mantisa.service";
import {Mantisi} from "../Mantisi";
import {Observable} from "rxjs/Observable";
import {DataSource} from "@angular/cdk/collections";
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import {MatSort} from '@angular/material';
@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent{
  displayedColumns = ['projekt', 'manits', 'kategorija','ozbiljnost','datum_prijave','postavio','odjel','postavio','naziv','status','planirana_isporuka'];
  constructor(private user:UserService, private dohvatMantisa:DohvatMantisaService) {
  }
  dataSource: TableDataSource | null;
  mantisi: Mantisi[];
  name = this.user.getUsername();
  @ViewChild(MatSort) sort: MatSort;
  ngOnInit() {
    this.dataSource = new TableDataSource(this.dohvatMantisa,this.sort);
  }
}

export class TableDataSource extends DataSource<Mantisi>{
  constructor(private mantisiDS: DohvatMantisaService,private sort: MatSort){
    super();
  }
  connect(): Observable<Mantisi[]> {
    const displayDataChanges = [
      this.mantisiDS.dohvatiMantise(),
      this.sort.sortChange,
    ];

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

  getSortedData(): Mantisi[]{
    const data = this.mantisiDS.prikazMantisa().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 'projekt': [propertyA, propertyB] = [a.projekt, b.projekt]; break;
        case 'manits': [propertyA, propertyB] = [a.manits, b.manits]; break;
        case 'kategorija': [propertyA, propertyB] = [a.kategorija, b.kategorija]; break;
        case 'ozbiljnost': [propertyA, propertyB] = [a.ozbiljnost, b.ozbiljnost]; break;
        case 'datum_prijave': [propertyA, propertyB] = [a.datum_prijave, b.datum_prijave]; break;
        case 'postavio': [propertyA, propertyB] = [a.postavio, b.postavio]; break;
        case 'naziv': [propertyA, propertyB] = [a.naziv, b.naziv]; break;
        case 'status': [propertyA, propertyB] = [a.status, b.status]; break;
        case 'planirana_isporuka': [propertyA, propertyB] = [a.planirana_isporuka, b.planirana_isporuka]; break;
      }

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

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

这是我的服务: dohvatMantisaService

import { Injectable } from '@angular/core';
import {Http, Response, RequestOptions, Headers} from "@angular/http";
import {Observable} from "rxjs/Observable";
import {Mantisi} from "./Mantisi";
import 'rxjs';
import 'rxjs/operator/map';
import 'rxjs/operator/do';

@Injectable()
export class DohvatMantisaService {
  constructor(public http:Http) { }
  result: Mantisi[];
  dohvatiMantise(): Observable<Mantisi[]>{
    return this.http.get('/mantis/getMantisReport').map(this.extractData);
  }
  private extractData(response: Response) {
    let body = response.json();
    return body || {};
  }

  prikazMantisa(): Mantisi[]{
    this.dohvatiMantise().subscribe(res => this.result = res);
    return this.result;
  }
}
Run Code Online (Sandbox Code Playgroud)

我正在为您提供我的dashboard.component.html matSort行:

<mat-table #table [dataSource]="dataSource" class="example-table" matSort>
Run Code Online (Sandbox Code Playgroud)

这里的主要问题是从http请求加载和获取数据,但我在控制台中遇到如下错误:

无法读取TableDataSource.webpackJsonp中的undefined属性'sortChange'.../../../../../src/app/dashboard/dashboard.component.ts.TableDataSource.connect(dashboard.component.ts: 36)在MatTable.webpackJsonp的MatTable.webpackJsonp .../../../cdk/esm5/table.es5.js.CdkTable._observeRenderChanges(table.es5.js:602).../.. /. ./cdk/esm5/table.es5.js.CdkTable.ngAfterContentChecked(table.es5.js:522)

它告诉我this.sort.sortChange是未定义的.我搜索了所有的互联网,但找不到合适的答案.希望你能帮助我.

neu*_*ing 49

如果使用"*ngIf"初始隐藏模板中的表容器,则视图字段将是未定义的.

  • 您可以使用容器并使用[ngClass] ='data!== undefined?"可见":"隐藏"...... css包含类和隐藏 - 在隐藏的情况下 - 元素:.hidden {visibility:hidden; } .visible {visibility:visible; } (4认同)
  • 如果需要在带有“ * ngIf”的节点中嵌套的mat-table,我们该怎么办? (2认同)
  • 这是一个很难发现的问题! (2认同)
  • 如果可以的话,我会投票赞成 10 次。非常难以调试和解决的问题。这个答案的伟大工作@neuralprocessing (2认同)
  • 非常感谢,为我的同事(没有足够的评分来评论)节省了至少两天的调试时间! (2认同)

Mik*_*ain 48

我刚遇到这个问题,而我所要做的就是确保你matSort viewChild正确引用你的文件,并确保你已经MatSortModule在import区域中添加了你的module.ts文件.

如下: @NgModule({ imports: [ MatSortModule, MatTableModule, ] )}

  • 它很有用,但它已经导入了.如果没有模块导入,您将收到诸如"您是否考虑将matSort实现为@NgModule声明?"之类的错误.此外,我已发布解决方案,以便您可以检查它. (2认同)
  • 实际上,没有模块导入我没有得到任何错误.它只是失败了因为MatSort在我尝试设置`sort`变量时未定义. (2认同)
  • 谷歌不太擅长编写文档,因此,仅通过遵循他们的示例,他们的代码就可以工作。这是我的问题。谢谢。 (2认同)
  • 只需将 MatSortModule 添加到 NgModule 导入中即可。这样做之后它就开始工作了。 (2认同)

Vin*_*rih 14

我找到了解决这个问题的方法.

主要问题是表在数据到达之前呈现.我首先加载了数据并将其像源一样发送到dataSource构造函数.之后,问题就消失了.这就是异步http.get和服务的问题.

谢谢你的帮助.

fetchData(id){
  this.fetch.getProcesses(id).subscribe(result => {
    this.processes = result;
    this.dataSource = new TableDataSource(this.processes);
    Observable.fromEvent(this.filter.nativeElement, 'keyup')
      .debounceTime(150)
      .distinctUntilChanged()
      .subscribe(() => {
        if (!this.dataSource) {
          return;
        }
        this.dataSource.filter = this.filter.nativeElement.value;
      });
  });
}




export class TableDataSource extends DataSource<Proces>{
  _filterChange = new BehaviorSubject('');
  get filter(): string {
    return this._filterChange.value;
  }
  set filter(filter: string) {
    this._filterChange.next(filter);
  }
  filteredData: any =[];

  constructor(private processes:Proces[]){
    super();
  }
  connect(): Observable<Proces[]>{
    const displayDataChanges = [
      this.processes,
      this._filterChange,
    ];
    return Observable.merge(...displayDataChanges).map(() => {
      this.filteredData = this.processes.slice().filter((item: Proces) => {
        const searchStr = (item.name).toLowerCase();
        return searchStr.indexOf(this.filter.toLowerCase()) !== -1;

      });
      return this.filteredData;
    })
  }
  disconnect(){}
}



      <div class="header">
    <mat-form-field floatPlaceholder="never">
      <input matInput #filter placeholder="Pretraži procese">
    </mat-form-field>
  </div>
  <mat-table #table [dataSource]="dataSource" class="table-mantis" matSort>

    <ng-container matColumnDef="col1">
      <mat-header-cell *matHeaderCellDef class="table-header-cell" mat-sort-header> Name</mat-header-cell>
      <mat-cell *matCellDef="let row" class="example-cell" > {{row.nazivProcesa}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="col2">
      <mat-header-cell *matHeaderCellDef class="table-header-cell" mat-sort-header> Cell 2</mat-header-cell>
      <mat-cell *matCellDef="let row" class="example-cell" > {{row.nazivVlasnika
        }} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="col3">
      <mat-header-cell *matHeaderCellDef class="table-header-cell" mat-sort-header> Cell 3</mat-header-cell>
      <mat-cell *matCellDef="let row" class="example-cell" > {{row.interniAkt}} </mat-cell>
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns" class="example-header-row"></mat-header-row>
    <mat-row class="example-row" *matRowDef="let row; columns: displayedColumns;"></mat-row>
  </mat-table>
Run Code Online (Sandbox Code Playgroud)


Geo*_*Cs. 7

对于 Angular 8 和 Material 6.4.1,如果您等待从服务接收数据,修复 MatSort 和 MatPaginator 的最简单和最好的方法是设置static: false而不是 true,如下所示:

@ViewChild(MatSort, { static: false }) sort: MatSort;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
Run Code Online (Sandbox Code Playgroud)

就我而言,是对数据的 ngOnChanges 调用。


小智 5

我遇到了相同的问题,并通过添加以下内容进行了修复:

@ViewChild(MatSort) set matSort(ms: MatSort) {
this.sort = ms;
this.setDataSourceAttributes();
 }

@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
 this.paginator = mp;
this.setDataSourceAttributes();
 }

setDataSourceAttributes() {
  this.dataSource.paginator = this.paginator;
  this.dataSource.sort = this.sort;
  }
Run Code Online (Sandbox Code Playgroud)

  • 这有效,谢谢。对于 Angular 8,我只需添加选项 `static: false` - `@ViewChild(MatSort, { static: false }) set matSort(ms: MatSort)` (2认同)

Vis*_*hra 5

所以它的发生是因为你的this.sort.sortChange方法在你的子视图初始化之前被调用

你只需要从AfterViewInit而不是OnInit实现你的类

并使用ngAfterViewInit生命周期方法

export class ApplicantListComponent implements AfterViewInit {
    @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
    @ViewChild(MatSort, { static: false }) sort: MatSort;

    constructor() {}

    ngAfterViewInit() {
        this.sort.sortChange.subscribe(() => {
            this.paginator.pageIndex = 0;
            this.paginator.pageSize = this.pageSize;
        });
} 
Run Code Online (Sandbox Code Playgroud)