2017-07-19 5 views
0

In meinem Angular-Programm versuche ich ein Array basierend auf einem anderen Array zu filtern. Ich möchte nur den Namen von Personen anzeigen (aus empInfo Array), die einen Wert von etoEarned für die type-Eigenschaft in der ptoData-Array haben. Das empInfo Array ist eine Liste aller Mitarbeiter mit ihren Mitarbeiterdetails, und das ptoData Array ist eine Liste aller Tage, die jemand genommen hat. In beiden Feldern gibt es ein Feld EmpKey, das angibt, welcher Mitarbeiter welche freien Tage genommen hat. Im Moment zeigt es alle an und gibt nur Werte für diejenigen aus, die sie haben und sieht so aus: enter image description hereHerausfiltern eines Arrays basierend auf einem anderen Array

Wie kann ich die Namen eliminieren, die keine zugewiesenen Stunden haben?

Hier Funktionen, die meine Taste Anrufe:

setValues(): void { 
 
     this.datePTO = this.ptoData.filter(pto => pto.date > this.StartDate && pto.date < this.EndDate); 
 
     this.etoEarned = this.datePTO.filter(pto => pto.type === 'etoEarned'); 
 
     
 
     setTimeout(() => { this.printMonthlyReport() }, 2000); 
 
    } 
 

 
    printMonthlyReport(): void { 
 

 
     let printContents, printAdjContents, popupWin, popupWinAdj; 
 
     printAdjContents = document.getElementById('print-monthly-eto-report').innerHTML; 
 
     popupWinAdj = window.open('', '_blank', 'top=0,left=0,height=100%,width=auto'); 
 
     popupWinAdj.document.open(); 
 
     popupWinAdj.document.write(` 
 
      <html> 
 
      <head> 
 
       <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> 
 
       <title>Monthly Adjusted Report</title> 
 
      </head> 
 
      <body> 
 
       ${printAdjContents} 
 
      </body> 
 
      </html>` 
 
     ); 
 
    }

und hier ist mein html:

<div id="print-monthly-eto-report" style="border: none; display: none;"> 
 

 
     <div class="panel-body col-sm-12" *ngFor="let emp of empInfo"> 
 
     <div *ngIf="empHasEto(emp)> 
 
      <table class="table"> 
 
      <thead> 
 
       <tr> 
 
       <td colspan="4" style="font-weight: bold;">Employee: {{emp.FirstName}} {{emp.LastName}}</td> 
 
       </tr> 
 
       <tr> 
 
       <td>Date</td> 
 
       <td>Hours</td> 
 
       <td>Scheduled</td> 
 
       <td>Notes</td> 
 
       </tr> 
 
      </thead> 
 
      <tbody> 
 
       <ng-container *ngFor="let eto of etoEarned"> 
 
        <tr *ngIf="eto.EmpKey === emp.EmpKey"> 
 
         <td>{{eto.date | date: 'MM/dd/yyyy'}}</td> 
 
         <td>{{eto.hours}}</td> 
 
         <td>{{eto.scheduled}}</td> 
 
         <td>{{eto.notes}}</td> 
 
        </tr> 
 
        </ng-container> 
 
      </tbody> 
 
      <tfoot> 
 
       <tr> 
 
       <td colspan="4"><span style="font-weight:500;">Total ETO Hours Earned: {{emp.ETOEarned}}</span></td> 
 
       </tr> 
 

 
      </tfoot> 
 
      </table> 
 
     </div> 
 
     </div> 
 
     </div>

EDIT - Ich habe eine Funktion hinzugefügt (Danke an @LarsMontanaro) und es hat das Problem der Anzeige des Namens aller Personen behoben, aber immer noch Platz für jede Person. Ich nehme an, das Problem ist mein HTML, weil ich let emp of empInfo vor *ngIf="empHasEto(emp) habe, so wird es immer noch durch jede Person gehen, aber nur die Tabelle für diejenigen anzeigen, die wahr zurückkehren. Wie kann ich das beheben, um den Leerraum zu entfernen? (Als Referenz hier ist, wie es aussieht):

enter image description here

Auch hier ist meine neue Funktion (ich habe die .html oben aktualisiert):

empHasEto(emp: EmpInfo) { 
 
     this.datePTO = this.ptoData.filter(pto => pto.date > this.StartDate && pto.date < this.EndDate); 
 
     this.etoEarned = this.datePTO.filter(pto => pto.type === 'etoEarned'); 
 

 
     if (this.empInfo && this.etoEarned) { 
 
      for (let eto of this.etoEarned) { 
 
       if (eto.EmpKey == emp.EmpKey) { 
 
        return true; 
 
       } 
 
      } 
 
     } 
 
    }

Antwort

1

EDIT: Eine bessere Methode, dies zu tun, ist eine Pipe zu verwenden, um das Array zu filtern, über das Sie iterieren.

Sie können wie so ein eigenes Rohr erstellen:

import { Pipe, PipeTransform } from '@angular/core'; 

@Pipe({ 
    name: 'filterEmployeesByEto' 
}) 
export class FilterEmployeesByEtoPipe implements PipeTransform { 
    transform(empArray : Array<any>, etoArray : Array<any>): Array<any> { 
     if (empArray && etoArray) { 
      return empArray.filter((emp) => { 
       for (let eto of etoArray) { 
        if (eto.EmpKey === emp.EmpKey) { 
         return true; 
        } 
       } 
      } 
     } 
    } 
} 

und dann die Pfeife in der HTML-Zeile rufen Sie die * ngFor wie so enthält:

<div class="panel-body col-sm-12" *ngFor="let emp of empInfo | filterEmployeesByEto : etoEarned"> 

Sie müssen Ihre Pfeife registrieren in deiner App-module.ts.

A SO Stelle, die genau dieses Verfahren näher erläutert, ist hier: How to apply filters to *ngFor

Und Sie können über Angular Benutzerdefinierte Pipes hier lesen: https://angular.io/guide/pipes#custom-pipes

+0

diese Art von geholfen (siehe aktualisiert in OP), aber es zeigt immer noch Platz von wo die Mitarbeiter waren – asdf

+0

ah, natürlich habe ich eine bessere Lösung. Du musst eine Pfeife benutzen!Gib mir ein paar Minuten und ich werde meine Antwort bearbeiten. – LarsMonty

+0

das hat super funktioniert! Ich habe nicht mal an eine Pfeife gedacht, danke! – asdf

Verwandte Themen