我将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);
});
}
}
这是我的服务: 的 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;
}
}
我正在为您提供我的dashboard.component.html matSort行:
<mat-table #table [dataSource]="dataSource" class="example-table" matSort>
这里的主要问题是数据是从http请求加载和获取的,但我在控制台中遇到的错误是这样的:
无法读取未定义的属性'sortChange' 在TableDataSource.webpackJsonp ... / .. / .. / .. / .. / src / app / dashboard / dashboard.component.ts.TableDataSource.connect(dashboard.component.ts:36) 在MatTable.webpackJsonp ... / .. / .. / cdk / esm5 / table.es5.js.CdkTable._observeRenderChanges(table.es5.js:602) 在MatTable.webpackJsonp ... / .. / .. / cdk / esm5 / table.es5.js.CdkTable.ngAfterContentChecked(table.es5.js:522)
它告诉我 this.sort.sortChange 未定义。 我搜索了所有的互联网,但找不到合适的答案。希望你能帮助我。
答案 0 :(得分:35)
如果使用“* ngIf”初始隐藏模板中的表容器,则视图字段将是未定义的。
答案 1 :(得分:35)
我遇到了这个问题,而我所要做的就是确保您正确引用matSort viewChild
并确保在您的module.ts文件中添加了MatSortModule
进口区。
如下所示:
@NgModule({
imports: [
MatSortModule,
MatTableModule,
]
)}
答案 2 :(得分:12)
我找到了解决这个问题的方法。
主要问题是在数据到达之前呈现了表。我首先加载了数据并将其像源一样发送到dataSource构造函数。之后,问题就消失了。这就是async http.get和services。
谢谢你的帮助。
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>
答案 3 :(得分:5)
使用Angular 8和Material 6.4.1时,如果您等待从服务接收数据,则修复MatSort和MatPaginator的最简单最好的方法是将 static:false 设置为true,像这样:
@ViewChild(MatSort, { static: false }) sort: MatSort;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
就我而言是ngOnChanges数据调用。
答案 4 :(得分:3)
我遇到了同样的问题,并通过添加以下内容解决了该问题:
@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;
}
答案 5 :(得分:1)
之所以会这样,是因为在您的子视图“初始化”之前,您会调用 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;
});
}
答案 6 :(得分:0)
将异步数据从容器层传递到组件层时,我遇到了类似的问题。这是我的解决方法
因为元素开始时没有数据,所以没有像 original example 那样放置构造函数或OnInit的方法。只有在数据流进入(异步)之后,我才在setter中实现sort和paginator,并且一切正常。
在我的模板中:
<div class="card">
<div class="card-header">
<h4>{{pageTitle}}</h4>
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
</div>
<div class="card-body p-0">
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="projectNumber">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Werf Nummer </th>
<td mat-cell *matCellDef="let row"> W{{row.projectNumber}} </td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Omschrijving </th>
<td mat-cell *matCellDef="let row"> {{row.description}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;">
</tr>
</table>
<mat-paginator [pageSizeOptions]="[10,20,100]"></mat-paginator>
</div>
</div>
</div>
在我的角度分量类中,
export class ProjectListComponent {
pageTitle = 'Projects';
displayedColumns: string[] = ['projectNumber', 'description'];
dataSource: MatTableDataSource<Project>;
@ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
@ViewChild(MatSort, {static: true}) sort: MatSort;
@Input() set projects(value: Project[]){
this.dataSource = new MatTableDataSource(value);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
@Input() selectedProject: Project;
@Output() selected = new EventEmitter<Project>();
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
}
我应该提到一些关于过滤选项非常有趣的东西。请注意,这里的项目仅用于两个字段,但是接口实际上比该字段更多,例如它具有一个ID。即使我没有显示ID,也可以使用上面的代码对ID进行过滤,这真是太棒了。
export interface Project {
id: string;
projectNumber: string;
description: string;
activePeriods: ProjectActivePeriod[];
}
还要注意,您的displayColumns中的 matColumnDef =“ projectNumber” 引用必须是接口中属性的确切名称。如果我使用了“ P rojectNumber”,则排序将无法进行。
我根据
的信息进行构建答案 7 :(得分:0)
我遇到了同样的问题,
此问题有两个原因
import { MatSortModule, MatPaginatorModule, MatTableModule } from '@angular/material';
@NgModule({
imports: [MatSortModule, MatPaginatorModule, MatTableModule],
exports: []
})
ngAfterViewInit() {
this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0 );
}
答案 8 :(得分:0)
如果数据在一个对象内,排序也不起作用。例如:
interface: Name { firstName: string; lastName: string; }
interface: User { name: Name; }
{{ user.Name.firstName }}
排序在这种情况下不起作用。它需要像:{{ user.firstName }}
此外,属性名称和列名称必须匹配。
答案 9 :(得分:0)
对我来说,我忘了把 matSort
道具放在 <table/>
上。
<table mat-table matSort [dataSource]="dataSource">