69 votes

Erreur Angular6 Material6: "Il ne peut y avoir qu'une seule ligne par défaut sans une fonction prédicatrice when."

Je suis en train de mettre en place le Tableau avec des lignes extensibles depuis https://material.angular.io/components/table/examples mais je reçois cette erreur :

Il ne peut y avoir qu'une seule ligne par défaut sans une fonction prédicat when.

Cette erreur provient du fait que j'ai deux , tous deux sans prédicat when (comme dans l'exemple). Si j'en enlève un, alors l'erreur disparaît.

`D'après mes propres recherches, j’ai constaté que cette fonctionnalité est nouvelle dans Material. J'ai effectué une mise à niveau vers @angular/material@latest et @angular/cdk@latest et j'ai quand même reçu l'erreur.

Est-ce que quelqu'un sait ce que je dois faire pour mettre en œuvre le tableau comme dans l'exemple de la documentation? https://material.angular.io/components/table/examples

Mes versions :

Angular CLI: 6.0.8
Node: 8.11.2
OS: win32 x64
Angular: 6.0.4
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.6.8
@angular-devkit/build-angular     0.6.8
@angular-devkit/build-optimizer   0.6.8
@angular-devkit/core              0.6.8
@angular-devkit/schematics        0.6.8
@angular/cdk                      6.3.1
@angular/cli                      6.0.8
@angular/flex-layout              6.0.0-beta.16
@angular/material                 6.3.1
@ngtools/webpack                  6.0.8
@schematics/angular               0.6.8
@schematics/update                0.6.8
rxjs                              6.2.0
typescript                        2.7.2
webpack                           4.8.3`

185voto

GoTo Points 129
Il s'avère que je manquais de la directive multiTemplateDataRows dans la balise`

`

1 votes

Si vous rencontrez un problème avec 'sticky' indéfini, vérifiez votre définition de colonnes

0 votes

Comme dans matColumnDef?

0 votes

@BenTaliadoros comme vous pouvez le voir dans la balise ci-dessus, à la fin.

23voto

adamdport Points 495

Cette erreur pourrait également apparaître si la fonction dans votre prédicat when est indéfinie. Donc si vous avez

et que hasChild est indéfini, vous pourriez obtenir cette erreur.

0 votes

Cela m'a vraiment aidé, après la réponse acceptée. Merci!

3voto

J'ai eu le même problème. j'ai mis à jour @angular/cdk & @angular/material en 6.4.7. Et tout fonctionne bien. Bien sûr, vous avez également besoin de l'attribut multiTemplateDataRows

1 votes

Merci, multiTemplateDataRows n'a pas fonctionné sans mise à jour.

0voto

Gui Seek Points 11

Essayez comme ça :

wrapper-table.ts

import { SelectionModel } from '@angular/cdk/collections';
import { AfterContentInit, Component, ContentChildren, Input, QueryList, TemplateRef, ViewChild } from '@angular/core';
import { MatColumnDef, MatHeaderRowDef, MatRowDef, MatTable, MatTableDataSource } from '@angular/material/table';

@Component({
  selector: 'ui-wrapper-table',
  templateUrl: './wrapper-table.component.html',
  styleUrls: ['./wrapper-table.component.scss']
})
export class WrapperTable implements AfterContentInit {

  @ContentChildren(MatHeaderRowDef) headerRowDefs: QueryList;
  @ContentChildren(MatRowDef) rowDefs: QueryList>;
  @ContentChildren(MatColumnDef) columnDefs: QueryList;

  @ViewChild(MatTable, { static: true }) table: MatTable;

  @Input() columns: string[];

  @Input() dataSource: MatTableDataSource;

  @Input() contextTemplate: TemplateRef;

  @Input() selection: SelectionModel;

  ngAfterContentInit() {
    this.columnDefs.forEach(columnDef => this.table.addColumnDef(columnDef));
    this.rowDefs.forEach(rowDef => this.table.addRowDef(rowDef));
    this.headerRowDefs.forEach(headerRowDef => this.table.addHeaderRowDef(headerRowDef));
  }

  isAllSelected() {
    const numSelected = this.selection && this.selection.selected.length || 0;
    const numRows = this.dataSource && this.dataSource.data.length || 0;
    return numSelected === numRows;
  }
  masterToggle() {
    this.isAllSelected() ?
      this.selection.clear() :
      this.dataSource.data.forEach(row => this.selection.select(row));
  }
  checkboxLabel(row?: T): string {
    if (!row) {
      return `${this.isAllSelected() ? 'sélectionner' : 'désélectionner'} tout`;
    }
    return `${this.selection.isSelected(row) ? 'désélectionner' : 'sélectionner'} la ligne`;
  }
}

wrapper-table.html

   # 
     {{element.id}} 

   Création 
     {{element.created.toDate() | date}} 

   Contexte 

companies.component.ts

import { SelectionModel } from '@angular/cdk/collections';
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { MatSort, MatTableDataSource } from '@angular/material';
import { CompanyModel, GetAllCompaniesUsecase } from '@apps-waves/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
  selector: 'wave-companies',
  templateUrl: './companies.component.html',
  styleUrls: ['./companies.component.scss']
})
export class CompaniesComponent implements OnInit, OnDestroy {
  displayedColumns: string[] = ['select', 'name', 'companyType', 'created', 'context'];
  dataSource: MatTableDataSource;
  selection: SelectionModel;

  @ViewChild('sort', { static: false }) sort: MatSort;

  onDestroy = new Subject();

  constructor(
    private getAllCompanies: GetAllCompaniesUsecase
  ) { }

  ngOnInit() {
    this.getAllCompanies.execute()
      .pipe(takeUntil(this.onDestroy))
      .subscribe(companies => {
        this.dataSource = new MatTableDataSource(companies);
        this.selection = new SelectionModel(true, []);
        this.dataSource.sort = this.sort;
      })
  }

  onClick(company: CompanyModel) {
    console.log(company);
  }
  ngOnDestroy() {
    this.onDestroy.next();
    this.onDestroy.complete();
  }
}

companies.html

     Nom 
     {{element.name}} 

     Segment 
     {{element.companyType}} 

    edit

{{selection?.selected | json}}

Cela fonctionne très bien

0voto

Bertwin Romero Points 51

Votre modèle

mat-tree-node(*matTreeNodeDef="let node;when: hasChild", matTreeNodePadding)

et votre composant doit avoir une méthode appelée hasChild

hasChild = (_: number, node: FlatNode) => node.expandable;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X