2017-12-10 1 views
3

In meinem eckigen Projekt habe ich zwei Tabellen. Eine der Tabellen wird mit Daten aus einem Service geladen, und bei ngOnInit werden diese Daten zurückgegeben.Wann Funktion aufrufen, die Breite der Elemente berechnet?

Ich berechne die Breite der Kopfzeilenspalten und wende sie an eine andere Tabelle an. Und ich rufe this.resizeColumn() Funktion auf:

ngAfterViewInit() { 
this.resizeColumns();  
} 

Und auch auf:

@HostListener('window:resize') 
onResize() { 
this.resizeColumns(); 
} 

Das Problem ist, dass, wenn die Seite zum ersten Mal geöffnet wird, die Breiten, die berechnet werden werden noch nicht angewendet. Sobald ich das Fenster verkleinere, stimmen die beiden Header überein. Die Idee ist, dass, wenn sich die Tabellenbreite ändert, diese Funktion auch aufgerufen werden soll. Nach welchem ​​Event oder Lifecycle-Hook sollte ich resizeColumn aufrufen, so dass anfänglich beide Tabellen die gleiche Spaltenbreite haben?

+0

Obwohl scheint nicht gerade ein Duplikat zu mir, haben einen Blick auf diese Frage und die Kommentare für die akzeptierte Antwort https://stackoverflow.com/questions/47729202/change-element-width-dynamically- on-angular-5 –

+0

Vielen Dank. Ich habe es gelesen und habe einfach den gleichen Code ausprobiert, der in der angenommenen Antwort enthalten war. Aber das löst mein Problem nicht. Weil, sobald ich die Größe des Fensters ändere, dann erhält der Tabellenkopf die Werte. Ich habe versucht, etwas wie folgt zu implementieren: [link] (https://jsfiddle.net/pu4q1931/3/) Aber wie Sie sehen können, hat die Geige dieses Problem nicht, weil es JS hat. Ich weiß nicht, wie man dasselbe in eckigen tut, so dass, sobald das Programm ausgeführt wird, es diese Breiten nimmt. –

+0

In diesem Fall versuchen wir, das Problem zu lösen. Wenn Sie also die Seite im Code öffnen, werden die Breiten bereits korrekt berechnet, aber sie werden nicht angewendet oder sind erst verfügbar, wenn Sie die Größenänderung vorgenommen haben. –

Antwort

0

Sie können die Eigenschaftenbindung nutzen, um die Spaltenbreiten der beiden Tabellen zu verknüpfen, wie in this plunker gezeigt. In meinem Beispiel werden die Spaltenbreiten in der oberen Tabelle in regelmäßigen Abständen erhöht, und die Spaltenbreiten in der unteren Tabelle folgen mit der Eigenschaftenbindung.

<table> 
    <tr #table1Row> 
    <td>Column 1</td> 
    <td>Column 2</td> 
    <td>Column 3</td> 
    <tr> 
</table> 

<table> 
    <tr> 
    <td [style.width.px]="getColWidth(table1Row, 0)">Column 1</td> 
    <td [style.width.px]="getColWidth(table1Row, 1)">Column 2</td> 
    <td [style.width.px]="getColWidth(table1Row, 2)">Column 3</td> 
    <tr> 
</table> 
// Get the column width from Table 1 
public getColWidth(row: HTMLTableRowElement, index: number): number { 
    return row.cells[index].offsetWidth; 
} 


Update:

Wenn Sie die Änderung asynchron vornehmen müssen (eine Winkel Ausnahme zu vermeiden), können Sie den folgenden Code versuchen (implementiert in this plunker). Es ruft setTimeout auf, um die neue Breite nach dem aktuellen Ausführungszyklus zu erhalten.

private colWidths: Array<number> = [ 0, 0, 0 ]; 

public getColWidth(row: HTMLTableRowElement, index: number): number { 
    let width = row.cells[index].offsetWidth; 
    if (Math.abs(this.colWidths[index] - width) > 0.001) { 
    setTimeout(() => { 
     this.colWidths[index] = width; 
    }, 0); 
    } 
    return this.colWidths[index]; 
} 
+0

Aber ich ändere die Breite der Spalten mit der Eigenschaft Bindung. Das Problem besteht darin, dass die ursprüngliche Spaltenüberschrift ihre Breite basierend auf dem Inhalt erhält. Und wenn Sie die App zum ersten Mal starten, hat die Tabelle für einen Bruchteil einer Sekunde keine Daten (die Zielspalte erhält die Spaltenbreite der ursprünglichen Spalten) und dann erhält die Tabelle die Daten, die ursprünglichen Spalten breiten sich aus. Die Zielspalte bleibt gleich. Ich versuche zu verstehen, wie die Zielspalten ihre Breite ändern können, wenn sich die ursprünglichen Tabellenspalten geändert haben. Ich verwende @ViewChildren, um das native Element zu bekommen –

+0

Ich habe meine Funktion zu diesem früheren geändert: [link] (https://stackoverflow.com/questions/47729202/change-element-width-dynamically-on-angular-5) Und ich bin mir nicht sicher, wie man die Änderungen der Tabelle vornimmt, um die Berechnungen abzufeuern und die Breiten zu erhalten. –

+0

In meinem Beispiel sind die Breiten in Tabelle 2 mit den tatsächlichen Breiten in Tabelle 1 verknüpft (gemessen mit 'offsetWidth'). Wenn sich die Breiten in Tabelle 1 ändern, um sich an ihren Inhalt anzupassen, folgen die Breiten in Tabelle 2 mit Hilfe der Eigenschaftsbindung. Ich habe [my Plunker] (https://plnkr.co/edit/NuRo3WBwAwwmdpsrwwOM?p=preview) angepasst, um das Ergebnis für eine Inhaltsänderung in Tabelle 1 anzuzeigen. Bitte beachten Sie, dass Sie mit dieser Eigenschaftsbindung nicht müssen Überwachen Sie ein Ereignis, und Sie müssen nicht wissen, wenn sich die Breiten in der ersten Tabelle ändern. Der Mechanismus zur Erkennung von Winkeländerungen kümmert sich darum. – ConnorsFan

Verwandte Themen