如何解决角材料筛选器谓词“无法读取MatTableDataSource.filterPredicate上未定义的属性'toString'”
我正在使用.net核心Web API开发一个角度项目。 在具有表的组件中,首先我使用仅适用于一个参数的全局过滤器,但是客户请求希望对过滤器更加具体,因此我决定使用过滤谓词。 我遵循了此示例https://medium.com/@sevriukovmk/angular-mat-table-filter-2ead680c57bb,但是当我开始写任何过滤器的任何输入时,控制台会说:
错误TypeError:无法读取未定义的属性'toString' 在MatTableDataSource.filterPredicate的第766行(在ts代码中,在 createFilter()函数中用粗体和斜体标记)。 我试图查看带console.log(row)的“ createFilter()”函数的行是什么,并仅向我显示对象的第一行:
所以,我不知道这样做的原因是什么。有人可以帮我吗?感谢您的建议!
带来api的对象是这样的:
0: {group: "Mayo de 2021"}
1:anio: 2021
etapa: (32) [{…},{…},{…}]
fechaCreacion: null
fechaPactada: null
fechaProd: null
idCliente: 1
idClienteNavigation: {idCliente: 1,nombreCli: "SCHLUMBERGER DEL EcuaDOR"}
idTipoTransfo: 4
idTipoTransfoNavigation: null
idTransfo: 2220
mes: 5
nombreCli: "SCHLUMBERGER DEL EcuaDOR"
nucleos: "c"
oPe: 2482
oTe: 11624
observaciones: null
potencia: 500
prioridad: 0
rangoFin: 2
rangoInicio: 2
__proto__: Object
2: {idTransfo: 2256,oPe: 258,oTe: 369,observaciones: null,rangoInicio: 200,…}
3: {idTransfo: 2258,oPe: 654,oTe: 3210,observaciones: "second proof",rangoInicio: 300,…}
4: {idTransfo: 2260,oPe: 7913,oTe: 3031,rangoInicio: 1,…}
5: {idTransfo: 2255,oPe: 1973,oTe: 2021,observaciones: "proof",rangoInicio: 2,…}
6: {group: "Octubre de 2020"}
7: {idTransfo: 2250,oPe: 159753,oTe: 159753,observaciones: "lago",rangoInicio: 0,…}
ts组件是这样的:
import { Component,OnInit,Inject,ViewChild,Input,Output,EventEmitter,ngzone } from '@angular/core';
import { Transformadores } from '../models/transformadores';
import { TransformadoresService } from '../services/transformadores.service';
import { ActivatedRoute } from '@angular/router';
import { ErrorStateMatcher } from '@angular/material/core';
import { FormControl,FormGroupDirective,NgForm,Validators,FormBuilder,FormGroup } from '@angular/forms';
import {
MatDialog,MatDialogRef,MAT_DIALOG_DATA,MatDialogConfig
} from "@angular/material/dialog";
import { ClienteService } from '../services/cliente.service';
import { Cliente } from '../models/cliente';
import { TipoTransfo} from '../models/tipoTransfo';
import { MatSnackBar } from '@angular/material/snack-bar';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource,MatTable} from '@angular/material/table';
import { EtapaService } from '../services/etapa.service';
import { Etapa } from '../models/etapa';
import { TipoEtapaService } from '../services/tipo-etapa.service';
import {TipoEtapa} from '../models/tipoEtapa';
import { Observable,forkJoin } from 'rxjs';
import { tap,take } from 'rxjs/operators';
import { TransformadoresEtapas } from '../models/transformadoresEtapas';
import { Vista } from '../models/Vista';
import { TipoTransfoService } from '../services/tipoTransfo';
import { ExcelService } from '../services/excel.service';
import { Colores } from '../models/colores';
import { ColoresService } from '../services/colores.service';
import { EtapaTransfo } from '../models/etapaTransfo';
import {map,startWith} from 'rxjs/operators';
import * as jQuery from 'jquery';
import { MatPaginator } from '@angular/material';
const MAP_NOMBRE_ETAPA: { [tipoEtapa: string]: number} = {
"documentacion":1,"bobinaBT1":2,"bobinaBT2":3,"bobinaBT3":4,"bobinaAT1":5,"bobinaAT2":6,"bobinaAT3":7,"bobinaRG1":8,"bobinaRG2":9,"bobinaRG3":10,"bobinaRF1":11,"bobinaRF2":12,"bobinaRF3":13,"ensamblajeBobinas":14,"corteYPlegadoPYS":15,"soldaduraPYS":16,"envioPYS":17,"nucleo":18,"montaje":19,"horno":20,"cYPTapaCuba":21,"tapa":22,"radiadoresOPaneles":23,"cuba":24,"tintasPenetrantes":25,"granallado":26,"pintura":27,"encubado":28,"ensayosRef":29,"terminacion":30,"envioADeposito":31,"envioACliente":32
}
@Component({
selector: 'etapa-column-component',template: `
<ng-container *ngIf="etapa">
<div style="height:64px;line-height:64px" [style.background-color] = "etapa.idColorNavigation ? etapa.idColorNavigation.codigoColor : 'white'" [matTooltip]="etapa.idColorNavigation ? etapa.idColorNavigation.leyenda : '' ">
<span style="padding-left:10px;" *ngIf="etapa.dateFin" >{{etapa.dateFin | date:'dd/MM/yyyy'}}</span>
<span style="padding-left:10px;" *ngIf="(etapa.tiempoParc)!='Finalizada' && (etapa.tiempoParc)!=null" >{{etapa.tiempoParc}}</span>
<span>
<button mat-icon-button *ngIf="!etapa.dateIni" style="line-height:64px" (click)=asignarRef(etapa) matTooltip="Asignar referencia"><mat-icon>done</mat-icon></button>
</span>
<!--<span ></span>-->
</div>
</ng-container>
`,styleUrls: ['./transformadores-reloaded.component.css']
})
export class EtapaColumnComponent{
coloresArr:Colores[]=[];
etapaSelected:Etapa;
@input() etapa:Etapa; actualizar:Boolean;
@Output() actualizado=new EventEmitter<Boolean>();
constructor(){}
}
@Component({
selector: 'app-transformadores-reloaded',templateUrl: './transformadores-reloaded.component.html',styleUrls: ['./transformadores-reloaded.component.css']
})
export class TransformadoresReloadedComponent implements OnInit {
isLoadingResults = true;
dataGetTrafos:MatTableDataSource<any>;
dataExcel:TransformadoresEtapas[];
data3:Cliente[]=[];
data4:Etapa[]=[];
diego:ComboClientes[]=[];
idTransfo:number;
durationInSeconds=3;
data2:Transformadores;
data5:Etapa[]=[];
data6:TipoEtapa[]=[];
data7:EtapaTransfo[]=[];
mensajeSnack:string;
arrayBool:boolean;
muestre:boolean=false;
vista:Vista[];
datatipoTransfo:ComboTipoTransfo[]=[];
data8TipoTransfo:TipoTransfo[]=[];
colores:Colores[]=[];
displayedColumns1:string[]=['Accion']
displayedColumns2:string[]=[
'oTe','nucleos','oPe','rangoInicio','rangoFin','observaciones','potencia','nombreCli','fechaPactada','fechaProd'
]
//
etapasColumns: string[]= Object.keys(MAP_NOMBRE_ETAPA);
// TODAS las columnas
allColumns: string[]= this.displayedColumns1.concat(this.displayedColumns2).concat(this.etapasColumns);
dataSource;
etapasActualizadas:boolean;
form=new FormGroup(
{
oTe:new FormControl(),nucleos:new FormControl(),oPe :new FormControl(),rangoInicio :new FormControl(),rangoFin:new FormControl(),observaciones:new FormControl(),potencia :new FormControl(),nombreCli :new FormControl(),fechaPactada:new FormControl(),fechaProd:new FormControl(),}
)
oTe= '';
nucleos='';
oPe= '';
rangoInicio= '';
rangoFin= '';
observaciones= '';
potencia= '';
nombreCli= '';
// fechaPactada= '';
// fechaProd: ''
@ViewChild(MatSort,{static: true}) sort: MatSort;
@ViewChild(MatTable,{ static: false }) matTable: MatTable<any>;
@ViewChild(MatPaginator) paginator: MatPaginator;
constructor(private ngzone: ngzone,private transformadoresService: TransformadoresService,private
clientesService: ClienteService,public dialog: MatDialog,private route: ActivatedRoute,private
_snackBar: MatSnackBar,private etapaService: EtapaService,private tipoEtapaService: TipoEtapaService,private tipoTransfoService: TipoTransfoService,private excelService: ExcelService,private
coloresService:ColoresService) {}
ngAfterViewInit() {
this.ngzone.onMicrotaskEmpty.pipe(take(5)).subscribe(()=>this.matTable.updateStickyColumnStyles());
}
ngOnInit(): void {
this.dataGetTrafos=new MatTableDataSource();
this.getTrafos();
this.dataGetTrafos.filterPredicate =this.createFilter();
this.dataGetTrafos.paginator = this.paginator;
this.dataGetTrafos.sort = this.sort;
this.getClientes();
this.getTipoTransfo();
}
//This is for get Etapas from etapa in every object
getEtapa(t:Transformadores,nombreEtapa: string): any {
let matchEtapa = t.etapa.filter(etapa => etapa.idTipoEtapa == MAP_NOMBRE_ETAPA[nombreEtapa]);
if(matchEtapa.length!=0)
{
return matchEtapa[0];
}
if(this.etapasActualizadas==true)
{
this.getTrafos();
}
}
actualizar(evento:any){
if(evento==true)
{
this.getTrafos();
}
}
getTrafos():void{
this.transformadoresService.getTrafos()
.subscribe(transfo => {
console.log(transfo);
this.isLoadingResults = true;
this.dataGetTrafos.data=transfo;
},err => {
this.isLoadingResults = false;
},() =>{
this.isLoadingResults=false;
}
);
}
isGroup(index,item): boolean{
return item.group;
}
//THIS IS THE FILTER
createFilter() {
return (row: any,filters: string) => {
console.log(row);
console.log(filters);
// split string per '$' to array
const filterarray = filters.split('$');
const oTe = filterarray[0];
const nucleos = filterarray[1];
const oPe = filterarray[2];
const rangoInicio = filterarray[3];
const rangoFin = filterarray[4];
const observaciones = filterarray[5];
const potencia = filterarray[6];
const nombreCli = filterarray[7];
const matchFilter = [];
// Fetch data from row
const columnOTe = row.oTe;
const columnNucleos = row.nucleos;
const columnope = row.oPe;
const columnRangoInicio = row.rangoInicio;
const columnRangoFin = row.rangoFin;
const columnObservaciones = row.observaciones;
const columnPotencia = row.potencia;
const columnNombreCli = row.nombreCli;
***THIS IS THE LINE WHERE IS THE ERROR***
// verify fetching data by our searching values
const customFilterOTe = columnOTe.toString().toLowerCase().includes(oTe);
const customFilterNucleos = columnNucleos.toLowerCase().includes(nucleos);
const customFilterOPe = columnope.toString().toLowerCase().includes(oPe);
const customFilterRangoInicio = columnRangoInicio.toString().toLowerCase().includes(rangoInicio);
const customFilterRangoFin = columnRangoFin.toString().toLowerCase().includes(rangoFin);
const customFilterObservaciones = columnObservaciones.toLowerCase().includes(observaciones);
const customFilterPotencia = columnPotencia.toString().toLowerCase().includes(potencia);
const customFilterNombreCli = columnNombreCli.toLowerCase().includes(nombreCli);
// push boolean values into array
matchFilter.push(customFilterOTe);
matchFilter.push(customFilterNucleos);
matchFilter.push(customFilterOPe);
matchFilter.push(customFilterRangoInicio);
matchFilter.push(customFilterRangoFin);
matchFilter.push(customFilterObservaciones);
matchFilter.push(customFilterPotencia);
matchFilter.push(customFilterNombreCli);
// return true if all values in array is true
// else return false
return matchFilter.every(Boolean);
};
}
applyFilter() {
const ot =this.form.get('oTe').value;
const nucl=this.form.get('nucleos').value;
const op=this.form.get('oPe').value;
const rI=this.form.get('rangoInicio').value;
const rF=this.form.get('rangoFin').value;
const obs=this.form.get('observaciones').value;
const pot=this.form.get('potencia').value;
const nC=this.form.get('nombreCli').value;
this.oTe = ot === null ? '' : ot;
this.nucleos = nucl === null ? '' : nucl;
this.oPe = op === null ? '' : op;
this.rangoInicio = rI === null ? '' : rI;
this.rangoFin = rF === null ? '' : rF;
this.observaciones = obs === null ? '' : obs;
this.potencia = pot === null ? '' : pot;
this.nombreCli = nC === null ? '' : nC;
// create string of our searching values and split if by '$'
const filterValue = this.oTe + '$' + this.nucleos + '$' + this.oPe+'$' + this.rangoInicio+'$' + this.rangoFin+'$' + this.observaciones+'$' + this.potencia+'$' + this.nombreCli;
this.dataGetTrafos.filter = filterValue.trim().toLowerCase();
console.log("THIS DATA GET TRAFOS: ",this.dataGetTrafos.filter);
}
}
html是这样的:
<mat-card class="titulo">
<mat-card-header>
<mat-card-title style="line-height:60px;">Transformadores</mat-card-title>
</mat-card-header>
<br>
</mat-card>
<div class="example-container mat-elevation-z8">
<div class="example-loading-shade"
*ngIf="isLoadingResults">
<mat-spinner *ngIf="isLoadingResults"></mat-spinner>
</div>
<!--Tabla transformadores-->
<div class="float " style="bottom:7vh;">
<button mat-fab color="primary" (click)="dialogAddTransfo()" >
<mat-icon>add</mat-icon>
</button>
</div>
<div class="float ">
<button mat-fab color="primary" (click)="export()">
<mat-icon><svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
width="24" height="24"
viewBox="0 0 172 172"
style=" fill:#000000;"><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,172v-172h172v172z" fill="none"></path><g fill="#ffffff"><path d="M86,21.5l-71.66667,14.33333v100.33333l71.66667,14.33333zM100.33333,35.83333v14.33333h14.33333v14.33333h-14.33333v14.33333h14.33333v14.33333h-14.33333v14.33333h14.33333v14.33333h-14.33333v14.33333h50.16667c3.956,0 7.16667,-3.21067 7.16667,-7.16667v-86c0,-3.956 -3.21067,-7.16667 -7.16667,-7.16667zM129,50.16667h14.33333v14.33333h-14.33333zM29.92643,59.46094h12.73763l6.62077,15.87305c0.5375,1.29717 0.94208,2.80149 1.35775,4.50716h0.18197c0.2365,-1.02483 0.7179,-2.59064 1.44173,-4.63314l7.37663,-15.74707h11.61784l-13.87142,26.30111l14.27734,26.77702h-12.3877l-7.97852,-17.30078c-0.301,-0.60917 -0.65799,-1.83567 -0.95182,-3.54134h-0.11198c-0.17917,0.817 -0.5403,2.04015 -1.0778,3.68132l-8.0485,17.16081h-12.44368l14.76725,-26.56706zM129,78.83333h14.33333v14.33333h-14.33333zM129,107.5h14.33333v14.33333h-14.33333z"></path></g></g></svg></mat-icon>
</button>
</div>
<table mat-table [dataSource]="dataGetTrafos" id="tabla">
<ng-container matColumnDef="Accion" id="Accion" sticky>
<th mat-header-cell *matHeaderCellDef > Accion </th>
<td mat-cell *matCellDef="let row" >
<button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Example icon-button with a menu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-icon-button class="editBorr" color="primary" (click)="dialogEditTransfo(row)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button style="color:teal;" class="editBorr" (click)="onRowClicked(row)" matTooltip="Procesos">
<mat-icon>av_timer</mat-icon>
</button>
<button mat-icon-button color="warn" class="editBorr" (click)="dialogDeleteTransfo(row)" >
<mat-icon>delete</mat-icon>
</button>
</mat-menu>
</td>
</ng-container>
<ng-container [formGroup]="form" *ngFor="let column of displayedColumns2" sticky matColumnDef="{{column}}">
<th mat-header-cell *matHeaderCellDef style="width:100px!important;padding-left:10px!important;text-align:center">
{{column}}
<mat-form-field style="width:50px;" floatLabel="never">
<mat-label>{{column}}</mat-label>
<input matInput [formControlName]="column" (keyup)="applyFilter()">
</mat-form-field>
</th>
<td mat-cell *matCellDef="let element"> {{column=='fechaPactada'|| column=='fechaProd' ? (element[column] | date:'dd/MM/yyyy') : (element[column])}} </td>
</ng-container>
<ng-container *ngFor="let column of etapasColumns;" matColumnDef="{{column}}" >
<th mat-header-cell *matHeaderCellDef style="padding:20px!important">
{{column}}
</th>
<td mat-cell *matCellDef="let element" >
<etapa-column-component [etapa]="getEtapa(element,column)" (actualizado)="actualizar($event)">
</etapa-column-component>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="allColumns;sticky: true" ></tr>
<tr mat-row *matRowDef="let row; columns: allColumns;"></tr>
<ng-container matColumnDef="groupHeader">
<td mat-cell *matCellDef="let row" colspan="999" style="width:100%;background-color:rgb(247,150,70)!important;text-align:left"><div class="grupo" style="margin-left:15px;"><strong>{{row.group}}</strong></div></td>
</ng-container>
<tr mat-row *matRowDef="let row; columns: ['groupHeader']; when: isGroup"></tr>
</table>
<mat-paginator [pageSizeOptions]="[10,25,100]" showFirstLastButtons></mat-paginator>
</div>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。