角材料筛选器谓词“无法读取MatTableDataSource.filterPredicate上未定义的属性'toString'”

时间:2020-10-28 11:02:25

标签: angular typescript filtering angular-material2 angular-material-7

我正在使用.net核心Web API开发一个角度项目。 在具有表的组件中,首先我使用仅适用于一个参数的全局过滤器,但是客户请求希望对过滤器更加具体,因此我决定使用过滤谓词。 我遵循了此示例https://medium.com/@sevriukovmk/angular-mat-table-filter-2ead680c57bb,但是当我开始写任何过滤器的任何输入时,控制台会说:

错误TypeError:无法读取未定义的属性'toString' 在MatTableDataSource.filterPredicate的第766行(在ts代码中,在 createFilter()函数中用粗体和斜体标记)。 我试图查看带console.log(row)的“ createFilter()”函数的行是什么,并仅向我显示对象的第一行: enter image description here

所以,我不知道这样做的原因是什么。有人可以帮我吗?感谢您的建议!

带来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, observaciones: null, 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>

0 个答案:

没有答案