0
votes

MatTable - Matériau angulaire: Impossible de trouver la colonne avec l'ID

J'essaye d'afficher un tableau "par programmation":

// Info for the docForm:
              const cusDocs = this.customer.docRefs;
              Object.keys(cusDocs).map(docType => {
                const currDocs = [];
                cusDocs[docType].forEach(doc => {
                  currDocs.push(this.customerService.createNewDoc(doc));
                });
                const matchForm = this.docForm.get(docType) as FormArray;
                currDocs.forEach(form => {
                  matchForm.push(form);
                });
              });
              Object.keys(this.docForm.value).map(docType => {
                const currForm = this.docForm.get(docType) as FormArray;
                if (currForm.value.length > 0) {
                  Object.keys(currForm.value).map(doc => {
                    const currentDoc = currForm.at(+doc).value;
                    const newDocRow = {
                      name: currentDoc.name,
                      uploadDate: currentDoc.uploadDate,
                      uri: currentDoc.uri,
                      comments: currentDoc.comment
                    };
                    if (!this.documents[docType]) {
                      this.documents[docType] = [];
                    }
                    this.documents[docType].push(newDocRow);
                    console.log(this.documents[docType]);
                  });
                }
              });
              console.log(this.documents);
              console.log(this.docColumns);

Où:

[...] this.docForm = this.fb.group({});
    Object.keys(this.docTypes).map(
      type => {
        this.docForm.addControl(type, this.fb.array([]));
        this.docs.push({
         typeName: this.docTypes[type],
         typeSelector: type
        });
    }
  );

et où le documents Les variables / docs / docFrom sont remplies avec ngOnInit () :

documents: object = {};
docColumns: string[] = ["name", "uploadDate", "uri", "comments"];
docs = [];
docForm: FormGroup;
docTypes: object = {
    fs: 'Financial Statements',
    id: 'Identity Document',
    ad: 'Bank Account Details',
    cd: 'Constitutional Document',
    pd: 'Power Document',
  };

Ensuite, s'il y a un client, un abonnement obtient les données à partir de la base de données ... et une fois que nous obtenons les informations, elles sont agrégées dans les variables:

<div [formArrayName]="doc.typeSelector">
                  {{ doc.typeSelector }}
</div>
<div *ngIf="documents[doc.typeSelector]">
     <mat-table
      [dataSource]="documents[doc.typeSelector]"
      *ngFor="let col of docColumns">
      <ng-container [matColumnDef]="col">
        <th mat-header-cell *matHeaderCellDef> {{ col | uppercase }} </th>
        <td mat-cell *matCellDef="let element"> {{ element[col] }} </td>
      </ng-container>
    <tr mat-header-row *matHeaderRowDef="docColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: docColumns;"></tr>
  </mat-table>
</div>
  • Le tableau de documents est utilisé par le DOM pour afficher un panneau d'extension
  • L ' objet docTypes est utilisé pour construire la variable précédente, correspondant à la réponse du serveur. Peut-être inutile mais au moment où j'ai construit cela, je voulais m'assurer que les informations du serveur correspondaient au DOM ...
  • docForm est un FormGroup contenant les 5 types de documents différents qui peuvent être téléchargés.
  • docColumns sont les colonnes affichées définies à l'avance.
  • Dernier point mais non le moindre, documents est le tableau de l ' objet utilisé pour définir les lignes.

Voici ce que rapportent les console.logs : Journaux + erreur

J'ai vu des questions similaires mais je ne suis pas sûr que mon erreur corresponde à ces cas ... Merci d'avance!

MODIFIER ---------------------- EDIT: La réponse d'Olipej ne semble pas résoudre mon problème ou j'ai du mal à comprendre d'où vient mon erreur.

J'ai fait un stackblitz reproduisant ma structure de données et l'erreur que j'obtiens: https://stackblitz.com/edit/mat-table-error-example

Captures d'écran de Stackblitz: entrez la description de l'image ici


0 commentaires

3 Réponses :


1
votes

Etes-vous sûr que le ou les objets que vous passez à matTable ont tous des propriétés correspondant aux identifiants de colonne?

Au début du modèle, vous vérifiez un élément dans 'documents' mais vous ne vérifiez jamais ses propriétés.

<div *ngIf="documents[doc.typeSelector]">

Bien sûr, vous ne devriez pas avoir à vérifier si des propriétés existent mais parce que vous obtenez l'erreur: 'Impossible de trouver la colonne avec l'identifiant "uploadDate"' Je ne pense pas l'objet que vous avez transmis possède en fait la propriété.

Si cela ne vous aide pas, pouvez-vous fournir un exemple stackblitz?


11 commentaires

Hé kebbaben! Merci pour votre réponse. Je ne suis pas sûr de ce que vous entendez par: "Au début du modèle, vous vérifiez un élément dans 'documents' mais vous ne vérifiez jamais ses propriétés. J'ai vérifié le doc.typeSelector et ce sont les bons: {'fs', 'cd', 'id' etc ...} . Vous pensez que mes problèmes surviennent au passage de ces variables?


Ou il se peut que le typeSelector ne corresponde pas au sélecteur réel du FormArray.


@Ardzii Désolé, j'ai mal interprété l'erreur. Le problème est que la table mat n'enregistre pas la définition de colonne. Soit la référence est invalide d'une certaine manière, soit elle ne s'initialise pas avant matTable d'une manière ou d'une autre. Vous pouvez essayer matColumnDef = "{{col}}" sur ng-container ou * matRowDef = "let row; columns: ['name', 'uploadDate', 'uri', 'comments'];" sur tr mat-row.


Hé kebbaben! Merci pour le suivi! Je vais essayer ces solutions et vous tenir au courant. De toute façon, je réorganisais et factorisais mes variables car c'était un peu le bordel ...


@Ardzii Vous devriez vérifier la réponse d'Ollpej. Cela résoudra probablement votre problème.


Merci kebbaben pour le suivi! Cela semble effectivement être la réponse à ma question.


Ne fonctionne toujours pas ... Voici un stackblitz: stackblitz.com/edit/angular-eh8jqu


@Ardzii le stackblitz que vous avez lié n'utilise même pas de table de tapis mais des panneaux d'extension. Cela ne semble même pas correspondre au code de la question d'origine. Pouvez-vous mettre à jour votre stackblitz?


Permettez-moi de changer le nom du stackblitz .... stackblitz.com/edit/mat- exemple d'erreur de table


@Ardzii changer le nom de l'url ne changera pas le contenu de votre code ... Votre question tourne autour de l'utilisation de matTable, mais votre exemple stackblitz ne l'utilise pas du tout! Vous devez repenser ce pour quoi vous avez besoin d'aide.


Il doit y avoir une sorte de bogue. Je peux clairement voir ma table de tapis dans le stackblitz lorsque je clique sur le lien ... Vérifiez dans la question principale



2
votes

Votre boucle ngFor est définie sur l'élément mat-table. Vous souhaitez utiliser la boucle sur l'élément ng-container pour remplir votre table de données. Vous générez maintenant plusieurs tables de tapis avec des données incorrectes.

Changez cela et vous verrez la magie opérer :)


8 commentaires

Salut Olipej! Soit je n'ai pas obtenu la réponse correctement, soit cela ne semble pas fonctionner non plus. Voici un lien vers un stackblitz reproduisant l'erreur: stackblitz.com/edit/angular-eh8jqu


Il n'y a pas de table de tapis dans votre stackblitz. Avez-vous mal lié?


@Ardzii? J'ai vu que vous n'aviez pas d'autres projets sur stackblitz. Est-ce une erreur ou pas? Sinon, je vous suggère de créer un nouveau projet angulaire localement ou stackblitz et de créer une table de tapis avec moins de données. De cette façon, vous pouvez saisir le concept et l'appliquer ensuite à votre plus grand projet.


Le lien fonctionne très bien pour moi ... J'ai commenté la partie mat-table pour prouver que les données sont là via un simple

avec un tas de

s.


Ici, j'ai changé le nom ... stackblitz.com/edit/mat-table-error -exemple me faire savoir si cela fonctionne mieux.


@Ardzii Okey ... Le problème était que l'exemple StackBlitz n'utilisait aucun composant mat-table. En savoir plus sur mat-table ici: material.angular.io/components/table/overview Si vous avez besoin d'aide pour autre chose, c'est une question différente et ce problème doit être marqué comme résolu et vous devez ouvrir un nouveau problème avec vos erreurs actuelles. Bonne chance!


Il doit y avoir une sorte de bogue. Je peux clairement voir ma table de tapis dans le stackblitz lorsque je clique sur le lien ... Vérifiez dans la question principale


Ahh vous commentez le code produisant une erreur ... Quelle façon sournoise de présenter un exemple d'erreur.



0
votes

Je crée une nouvelle réponse car je devrai couvrir plus que les commentaires ne le permettent.

Tout d'abord, vous avez lié un exemple de stackblitz qui ne correspond pas au code de votre question. Ni votre utilisation de mat-table ni vos données que vous souhaitez afficher. Les deux sont structurés différemment entre le code de la question et le code de l'exemple.

Je pense que vous devez d'abord vous demander ce que vous voulez accomplir. Ensuite, vous devez vous demander ce dont vous avez besoin pour résoudre le problème que vous rencontrez.

Maintenant, si vous pensez toujours que l'utilisation de mat-table est ce dont vous avez besoin, alors je vais vous aider à l'utiliser avec des colonnes dynamiques .

Pour commencer avec mat-table, il faut un tableau d'objets à afficher et une définition des identifiants de colonne.

<table mat-table [dataSource]="dataSource">
  <ng-container *ngFor="let col of displayedColumns" [matColumnDef]="col">
    <th mat-header-cell *matHeaderCellDef> {{col}} </th>
    <td mat-cell *matCellDef="let element"> {{element[col]}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

dataSource code > utilise ELEMENT_DATA qui est un tableau d'objets.

shownColumns est un tableau de chaînes d'identifiants et est la définition de chaque colonne. Notez que chaque chaîne de ce tableau doit correspondre à l'un des noms de propriété / variable de PeriodicElement , sensible à la casse .

Et voici comment vous utilisez mat -table.

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
}

const ELEMENT_DATA: PeriodicElement[] = [
  {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
  {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
  {position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
  {position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
  {position: 5, name: 'Boron', weight: 10.811, symbol: 'B'},
  {position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'},
  {position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N'},
  {position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O'},
  {position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F'},
  {position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne'},
];

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = ELEMENT_DATA;
}

mat-table nécessite une source de données pour afficher quoi que ce soit. Remarquez où je mets le * ngFor? Je l'ai mis sur le ng-container car un ng-container est une colonne. Je boucle sur affichésColonnes . Le tableau des identifiants, et utilisez-les pour obtenir les propriétés de element.

Voici un exemple fonctionnel

Bien que si les noms de propriété dans les objets de données que vous utilisez ne changent jamais. Vous n'avez même pas besoin de boucler les colonnes dynamiquement, et je vous recommande vraiment de simplement lire la documentation standard de angular mat-table et de tester l'exemple de code.

J'espère que cela vous aidera avec vos problèmes.


0 commentaires