web-dev-qa-db-fra.com

Composant d'arborescence CDK de matériau angulaire avec défilement virtuel

La documentation sur les composants de l’arbre CDK Matériau angulaire indique:

"Les arbres plats sont généralement plus faciles à styliser et à inspecter. Ils sont également plus adaptés aux variations de défilement, telles que le défilement infini ou virtuel "

Des idées comment appliquer le défilement virtuel à l'arbre plat CDK?

J'ai un arbre énorme à rendre et maintenant il est si lent et quand j'ouvre tous les nœuds de manière récursive, il plante.

J'ai essayé <cdk-virtual-scroll-viewport> @ angular/cdk-experimental, mais je n'ai pas compris comment l'intégrer au composant tree.

7
Ragnar

La fonction principale de la fenêtre d'affichage virtuelle consiste à suivre les événements de défilement et à vous informer des éléments actuellement affichés à l'écran. En utilisant ces informations, vous pouvez modifier la source de données de l’arbre pour ne représenter que les nœuds affichés à l’écran.

Le problème est qu’à l’heure actuelle, la fenêtre de visualisation ne fonctionne vraiment que pour les éléments de hauteur constante. Lorsque vous développez un nœud de l'arborescence, sa hauteur est incompatible avec celle des autres nœuds fermés. Pour contourner ce problème, vous pourrez peut-être ajouter les nœuds enfants à la source de données de la fenêtre d'affichage virtuelle chaque fois qu'un nœud est développé.

Pour l'instant, je vais ignorer le problème du nœud développé.

Pour obtenir un défilement virtuel de base avec l’arbre, ajoutez ceci à votre modèle:

<cdk-virtual-scroll-viewport itemSize="48" style="height: 200px;">
  <ng-container *cdkVirtualFor="let item of fullDatasource"></ng-container>

  <mat-tree [dataSource]="dataSource" [treeControl]="treeControl">...</mat-tree-node>
  </mat-tree>
</cdk-virtual-scroll-viewport>

Nous créons la fenêtre d'affichage en lui indiquant la taille de chaque nœud. Nous ajoutons ensuite la variable virtualForOf en transmettant la source de données complète afin que la fenêtre d'affichage sache quelle doit être sa hauteur. Cela risque peut-être de tromper un peu, car je pense que l'utilisation prévue de virtualForOf est que le modèle inclut les éléments à faire défiler, mais le garder vide semble fonctionner.

La seule chose qui reste à faire est de s'assurer que la source de données de l'arbre est uniquement les éléments visibles de la source de données complète. Nous allons changer la façon dont nous le déclarons initialement dans le constructeur, mais voici la partie la plus excitante:

  ngAfterViewInit() {
    this.virtualScroll.renderedRangeStream.subscribe(range => {
      console.log(range, 'range')
      this.dataSource.data = this.fullDatasource.slice(range.start, range.end)
    })
  }

Nous souscrivons à la variable renderedRangeStream qui émet une plage chaque fois que le défilement change. Chaque fois que cela se produit, nous définissons simplement la source de données égale à la tranche appropriée!

Stackblitz avec résultat J'espère que cela suffit pour vous aider à démarrer!

1
Benjamin Kindle