Le CD Angular Material CDK fournit un Directive
CdkScrollable
, qui vous permet d'écouter les ScrollEvent
s 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-content
Component
, 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?
<mat-sidenav-content cdkScrollable> </mat-sidenav-content>
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
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 :
<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.AfterViewInit
au lieu de OnInit
. Autant que je sache, @ViewChild
est résolu dans AfterViewInit
, OnInit
est probablement trop tôt.