Angular 4 Material tabla resaltar una fila


Estoy buscando una buena manera de iluminar toda la fila a en md-table.
Debo hacer directiva o qué?
¿Alguien puede ayudarme con esto?

<div class="example-container mat-elevation-z8">
  <md-table #table [dataSource]="dataSource">

    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

    <!-- ID Column -->
    <ng-container cdkColumnDef="userId">
      <md-header-cell *cdkHeaderCellDef> ID </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.id}} </md-cell>
    </ng-container>

    <!-- Progress Column -->
    <ng-container cdkColumnDef="progress">
      <md-header-cell *cdkHeaderCellDef> Progress </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.progress}}% </md-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container cdkColumnDef="userName">
      <md-header-cell *cdkHeaderCellDef> Name </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.name}} </md-cell>
    </ng-container>

    <!-- Color Column -->
    <ng-container cdkColumnDef="color">
      <md-header-cell *cdkHeaderCellDef>Color</md-header-cell>
      <md-cell *cdkCellDef="let row" [style.color]="row.color"> {{row.color}} </md-cell>
    </ng-container>

    <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
    <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>
  </md-table>
</div>

Tabla de: https://material.angular.io/components/table/overview

Author: Taison Morris, 2017-07-31

4 answers

Actualización para la Versión de Material Más Reciente (md > > mat):

Html:

<!-- Add the highlight class in row definiton of md-table -->
<!-- Add click event to pass the selected row index -->

<mat-row *cdkRowDef="let row; columns: displayedColumns;" 
         [ngClass]="{'highlight': selectedRowIndex == row.id}"
         (click)="highlight(row)">
</mat-row>

Respuesta original:

Puedes hacerlo usando ngClass y una bandera como selectedRowIndex. Siempre que se haga clic en el índice de fila es igual a selectedRowIndex, se aplicará la clase.

Plunker demo

Html:

<!-- Add the highlight class in row definiton of md-table -->
<!-- Add click event to pass the selected row index -->

<md-row *cdkRowDef="let row; columns: displayedColumns;" 
         [ngClass]="{'highlight': selectedRowIndex == row.id}"
         (click)="highlight(row)">
</md-row>

Css:

.highlight{
  background: #42A948; /* green */
}

Ts:

selectedRowIndex: number = -1;

highlight(row){
    this.selectedRowIndex = row.id;
}
 36
Author: Nehal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-24 02:13:54

En la página ejemplos de la tabla resumen explican el SelectionModel para el manejo de selecciones - que por cierto también maneja la selección múltiple. Me imagino que en el futuro esto es lo que se incorporará en las mejoras futuras, por lo que es una buena idea comenzar a usarlo ahora.

selection es un modelo de selección definido en tu componente. No pude encontrar ninguna documentación real para esto, pero la implementación es extremadamente simple.

selection = new SelectionModel<CustomerSearchResult>(false, null);

El primer parámetro es allowMultiSelect, por lo que para permitir que se seleccionen varios elementos a la vez, establézcalo en true. Cuando false, el modelo de selección deseleccionará cualquier valor existente cuando establezca un nuevo valor.

Luego agregue un evento de clic a select() la fila y cree su propia clase css para cuando se seleccione la fila.

   <mat-table>
        ...

        <mat-row *matRowDef="let row; columns: displayedColumns;"
                 [ngClass]="{ 'selected': selection.isSelected(row)}"
                 (click)="selection.select(row)"></mat-row>

    </mat-table>

La clase css que agregué está a continuación (el ejemplo aún no menciona el estilo) y luego solo necesita agregar a su css

.mat-row {
   min-height: 65px;

   &.selected {
       background: #dddddd;
   }
}

Si su color de fondo es demasiado oscuro, deberá agregar estilos usted mismo para invertir el color del texto.

Para manejar la selección use el evento onChange de selection.

    // selection changed
    this.selection.onChange.subscribe((a) =>
    {
        if (a.added[0])   // will be undefined if no selection
        {
            alert('You selected ' + a.added[0].fullName);
        }
    });

O alternativamente los elementos seleccionados están en this.selection.selected.

Espero que mat-table se mejore para casos comunes como este y no dejen todo en manos del desarrollador. Cosas como eventos de teclado, etc. sería bueno que se manejara automáticamente con respecto al modelo de selección.


Consejo: Tenga en cuenta que si crea su SelectionModel para un seleccione la colección con

selection = new SelectionModel<CustomerSearchResult>(false, []);

Entonces selection.selected.length será realmente 1 y no los elementos esperados 0. No hay comprobación para ver que el elemento pasado en realidad está en el modelo - es una clase muy, muy tonto. Así que ciegamente pone [0] como el elemento seleccionado. Usa null en su lugar. El código fuente deja claro por qué esto ocurre :

if (_isMulti) {
    initiallySelectedValues.forEach(value => this._markSelected(value));
  } else {
    this._markSelected(initiallySelectedValues[0]);
  }
 20
Author: Simon_Weaver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-08 02:03:48

Así que, me encontré con este problema también. Estoy usando el nuevo 'mat -' en lugar de ' md -', pero SUPONGO que será más o menos lo mismo...

<mat-row
    *matRowDef="let row; columns: myColumns; let entry"
    [ngClass]="{ 'my-class': entry.someVal }">
</mat-row>

No lo encontré en ninguna parte, solo lo intenté y resultó que funcionó, así que espero que sea correcto. La gran cosa fue etiquetar 'dejar entrada' al final de las otras cosas matRowDef. Siento llegar tan tarde a la fiesta. Espero que esto le haga bien a alguien.

 2
Author: Nick Landkamer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-04 20:37:50

No tenía identificadores únicos como la columna id en los datos de mi tabla, pero esto funcionó para mí (material 6):

HTML

 <tr mat-row *matRowDef="let row; columns: displayedColumns" 
     (click)="selectedRow = row" [ngClass]="{ 'selected': row === selectedRow }"> 
 </tr>

Añadir variable a TS

selectedRow;

(S)CSS

.selected {
  background-color: red;
}

Si desea hacer más cosas que solo estilo al seleccionar una fila, reemplace (click)="selectedRow = row" con (click)="selectRow(row)" y agregue esta función a su ts:

selectRow(row) {
    this.selectedRow = row;
    // more stuff to do...
}
 2
Author: Zuzze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-11 10:43:36