Estoy tratando de implementar una directiva de tabla receptiva en mi aplicación angular, que establece el ancho mínimo y máximo y el tamaño de fuente de las columnas en un MatTable .
Estos valores se basan en el ancho de los contenedores principales y el número de columnas.
La directiva obtiene las definiciones de columna como una matriz de cadenas de entrada (por ejemplo, ["ordernum","ordername","timestamp"])
Actualmente el código se ve así:
@Input('ResponsiveTable') columns: string[] = []; ... constructor( private el: ElementRef, private host: MatTable<any>, private breakpointObserver: BreakpointObserver ) {} .... ngOnInit(): void { //set table style props this.el.nativeElement.style.minWidth = minCellWidth * this.columns.length + 'px'; this.el.nativeElement.style.width = tableWidth + '%'; // //subscriptions this.subscriptions.push( this.host.contentChanged.subscribe(() => setTimeout(() => this.initStyle()) ) ); } ... initStyle() { //get tableSize const parentWidth = this.el.nativeElement.parentNode.clientWidth; this.maxColumnWidth = parentWidth / this.columns.length > minCellWidth ? parentWidth / this.columns.length : minCellWidth; //set the headers, and maxWidth this.el.nativeElement.querySelectorAll('th').forEach((header: any) => { header.style.maxWidth = this.maxColumnWidth + 'px'; header.style.fontSize = `calc(8px + 0.25vw + 0.5vw / ${this.columns.length})`; header.style.padding = '6px'; }); //set the table cells and maxWidth this.el.nativeElement.querySelectorAll('td').forEach((cell: any) => { cell.style.maxWidth = this.maxColumnWidth + 'px'; cell.style.fontSize = `calc(8px + 0.25vw + 0.5vw / ${this.columns.length})`; }); this.initBreakpointObserver(); this.tableWidth = this.el.nativeElement.width; }Creo que esto no es eficiente, porque cada vez que ocurre un cambio de contenido, tengo que consultar todas las celdas y encabezados para establecer su ancho máximo y mínimo.
Sería bueno agregar algo de CSS al elemento principal, que selecciona todas sus celdas de mat y encabezados de mat y establece su tamaño. Lamentablemente, no puedo usar una clase CSS clásica porque el valor del tamaño se basa en la cantidad de columnas de la tabla.
¿Hay alguna manera de agregar progmáticamente una clase CSS que seleccione todas las celdas secundarias y les aplique el estilo, incluso si se agrega una nueva fila?
¿O cuál podría ser una mejor solución?
Una mejor solución (en mi humilde opinión) sería no intentar calcular los tamaños de fuente en función del número de columnas en primer lugar.
En cambio, establecería diferentes clases de CSS en la cuadrícula según la cantidad de columnas. No será perfecto, pero nada es perfecto una vez que necesite cambiar el tamaño de fuente según el ancho del texto.
Si realmente necesita hacer el cálculo, al menos intente encontrar una forma de ejecutar la función solo cuando el conjunto actual de columnas difiera del último conjunto de columnas.
Solución aplicada actualmente, con el uso de parámetros CSS:
https://stackblitz.com/edit/angular-ivy-6p3ewl?file=src/app/responsive-table.directive.ts
De esta forma, las propiedades de la clase aplicada se pueden establecer dinámicamente.