web-dev-qa-db-fra.com

Matériel angulaire Sidenav cdk

Le CD Angular Material CDK fournit un DirectiveCdkScrollable, qui vous permet d'écouter les ScrollEvents d'un conteneur spécifique.
J'essaie maintenant d'accéder au CdkScrollable du MatSidenavContent, qui est ajouté par défaut.
Cependant, mes @ViewChild (CdkScrollable) et @ContentChild (CdkScrollable) ne sont pas toujours définis.

Mon Component ressemble à ceci:

<mat-sidenav-container>
    <mat-sidenav>Sidenav content</mat-sidenav>
    <div>Main content</div>
</mat-sidenav-container>

Le DOM résultant ressemble à ceci:

<mat-sidenav-container>
    <div class="mat-drawer-backdrop"></div>
    <div tabindex="-1" class="cdk-visually-hidden cdk-focus-trap-anchor"></div>
    <mat-sidenav>Sidenav content</mat-sidenav>
    <mat-sidenav-content cdkScrollable>
          <div>Main content</div>
    </mat-sidenav-content>
</mat-sidenav-container>

Le mat-sidenav-contentComponent, qui est généré automatiquement, utilise une directive CdkScrollable-, à laquelle j'ai besoin d'accéder.
Ma question est maintenant:
Est-il possible d'accéder à ce Directive et si oui, comment?

10
Springrbua
  1. Ajoutez à vos importations de module d'application: ScrollDispatchModule.
  2. Ajoutez cdkScrollable à votre contenu mat-sidenav:

<mat-sidenav-content cdkScrollable> </mat-sidenav-content>

  1. Dans votre composant racine:

a) injectez ScrollDispatcher depuis @ angular/cdk/overlay et abonnez-vous au défilement:

constructor(public scroll: ScrollDispatcher) {

    this.scrollingSubscription = this.scroll
          .scrolled()
          .subscribe((data: CdkScrollable) => {
            this.onWindowScroll(data);
          });
}

c) faire quelque chose lors du défilement, par ex. vérifier le décalage

private onWindowScroll(data: CdkScrollable) {
    const scrollTop = data.getElementRef().nativeElement.scrollTop || 0;
    if (this.lastOffset > scrollTop) {
      // console.log('Show toolbar');
    } else if (scrollTop < 10) {
      // console.log('Show toolbar');
    } else if (scrollTop > 100) {
      // console.log('Hide toolbar');
    }

    this.lastOffset = scrollTop;
  }

Documentation: https://material.angular.io/cdk/scrolling/api

12
Sebastian Denis

J'ai ouvert un problème sur @ angular/material il y a quelque temps et ils exposent maintenant l'instance CdkScrollable-.
Pour l'utiliser, vous devez accéder à MatSidenavContainer à l'aide de @ViewChild(MatSidenavContainer. Cette instance a un membre public scrollable, qui est l'instance CdkScrollable.
Un exemple peut être trouvé ici

Edit: Comme l'exemple n'est pas très complet et que quelques personnes ont du mal à l'implémenter, je vais écrire mon propre exemple ici:

[~ # ~] html [~ # ~] :

<mat-sidenav-container>
    <mat-sidenav #sidenav>
        Sidenav Content
    </mat-sidenav>
    <div>
        Main Content
    </div>
</mat-sidenav-container>

TypeScript:

import { Component, AfterViewInit, ViewChild } from '@angular/core';
import { MatSidenavContainer } from '@angular/material';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit  {
  @ViewChild(MatSidenavContainer) sidenavContainer: MatSidenavContainer;

    constructor() {
    }

    ngAfterViewInit() {
      console.log(this.sidenavContainer.scrollable);
    }
}

Important :

  1. N'utilisez pas <mat-sidenav-content>. Cette balise est générée automatiquement et elle a la directive cdkScrollable attachée. Si tu utilises <mat-sidenav-content> dans votre propre modèle, le scrollable ne sera pas défini.
  2. Utilisez AfterViewInit au lieu de OnInit. Autant que je sache, @ViewChild est résolu dans AfterViewInit, OnInit est probablement trop tôt.
4
Springrbua