web-dev-qa-db-fra.com

Rangées de table extensibles en angle 4 avec un matériau angulaire

Comment voulez-vous rendre les lignes extensibles dans les tables de matériaux angulaires? Une des exigences est que je dois utiliser le tableau de matériau angulaire . Je préférerais également utiliser l'accordéon matériel aux informations fournies ici .

Je veux cliquer sur la ligne et afficher des informations différentes pour chaque colonne. Je cherche quelque chose comme ci-dessous. Si vous cliquez sur la ligne 1, les lignes 2 et 3 apparaissent avec des données différentes.

 enter image description here

18
Simon

Comme mentionné ici par Andrew Seguin, cela est déjà réalisable: en utilisant le prédicat when.

Voir cet exemple: https://stackblitz.com/edit/angular-material-expandable-table-rows } _ (merci à Lakston)

demo

À l'intérieur de la balise mat-table, vous devez utiliser le composant mat-row avec une directive matRipple. Lorsque vous cliquez sur une ligne, l'élément de ligne est affecté à la variable expandedElement:

<mat-row *matRowDef="let row; columns: displayedColumns;"
        matRipple 
        class="element-row" 
        [class.expanded]="expandedElement == row"
        (click)="expandedElement = row">
</mat-row>

Mais maintenant, nous devons ajouter notre ligne développée, qui est masquée par défaut et sera affichée si l'utilisateur clique sur la ligne ci-dessus:

<mat-row *matRowDef="let row; columns: ['expandedDetail']; when: isExpansionDetailRow"
        [@detailExpand]="row.element == expandedElement ? 'expanded' : 'collapsed'"
        style="overflow: hidden"> 
</mat-row>

Important est le prédicat when déjà mentionné. Ceci appelle une fonction isExpansionDetailRow définie dans le composant lui-même et vérifie si la ligne a une propriété detailRow:

isExpansionDetailRow = (row: any) => row.hasOwnProperty('detailRow');

Depuis RC0, le premier paramètre est l'index:

isExpansionDetailRow = (i: number, row: any) => row.hasOwnProperty('detailRow');

Si vous voulez avoir une vue développée pour chaque ligne, vous devez ajouter un "ExpansionDetailRow" identifié par la propriété detailRow pour chaque ligne comme celle-ci:

connect(): Observable<Element[]> {
    const rows = [];
    data.forEach(element => rows.Push(element, { detailRow: true, element }));
    return Observable.of(rows);
}

Si vous souhaitez enregistrer la variable rows dans la sortie de la console, elle se présentera comme suit:

console output

ÉDITER: EXEMPLE COMPLET À L'AIDE DE LA DIRECTIVE

(Rangées extensibles de la table des matrices (tri, pagination et filtrage))

55
Philipp Kief

Ce n'est pas possible immédiatement, mais vous pouvez le résoudre avec un peu de code personnalisé. Jetez un coup d'œil à cette discussion et cette solution (pas de moi, mais la base de cette réponse).

En bref: utilisez la table des matières et ajoutez une méthode de clic aux lignes:

<md-row *mdRowDef="let row; columns: displayedColumns; let index=index" (click)="expandRow(index, row)" #myRow></md-row>

Ajoutez un composant pour la zone développée. Le row_detail.html contient le code HTML qui se trouve dans la zone développée.

@Component({
  selector: 'app-inline-message',
  templateUrl: 'row_detail.html',
  styles: [`
    :Host {
      display: block;
      padding: 24px;
      background: rgba(0,0,0,0.03);
    }
  `]
})
export class InlineMessageComponent {
  @Input() content1: string;
  @Input() content2: string;
}

Dans votre composant où la table vit, vous avez besoin de la méthode pour développer la ligne. Tout d'abord, ajoutez ceci à votre composant ...

expandedRow: number;
@ViewChildren('myRow', { read: ViewContainerRef }) containers;

... et ajoutez ensuite la méthode:

/**
   * Shows the detail view of the row
   * @param {number} index
   */
expandRow(index: number, row: DataFromRowFormat) {

    if (this.expandedRow != null) {
      // clear old message
      this.containers.toArray()[this.expandedRow].clear();
    }

    if (this.expandedRow === index) {
      this.expandedRow = null;
    } else {
      const container = this.containers.toArray()[index];
      const factory: ComponentFactory<InlineMessageComponent> = this.resolver.resolveComponentFactory(InlineMessageComponent);
      const messageComponent = container.createComponent(factory);

      messageComponent.instance.content1= "some text";
      messageComponent.instance.content2 = "some more text";
    }
}
4
Tobii

Voici comment vous pouvez le faire avec un matériau angulaire. Cet exemple inclut la pagination et un exemple avec mat-sort-header dans la colonne "name". Je devais remplacer la pagination mat et faire un tri personnalisé pour m'assurer que la ligne extensible était toujours par son parent lors de son tri. Cet exemple vous permet également d'ouvrir plusieurs lignes à la fois et de fermer toutes les lignes.

https://stackblitz.com/edit/angular-material2-issue-zs6rfz

1
Braden Brown

Lorsque CDK était le seul moyen d'obtenir quelque chose de proche d'un Material Table, utiliser des md-row dans une table normale était une alternative viable, mais depuis @angular/material 2.0.0-beta.12 a abandonné les tables CDK et dispose désormais de leurs propres tables de données qui pourraient répondre à vos besoins. Voir la documentation ci-dessous:

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