Angular-Material Sidenav CdkScrollable
Answer :
- Add to your app module imports:
ScrollDispatchModule
. - Add
cdkScrollable
to yourmat-sidenav-content
:
<mat-sidenav-content cdkScrollable> </mat-sidenav-content>
- In your root component:
a) inject ScrollDispatcher
from @angular/cdk/overlay
and subscribe to scrolling:
constructor(public scroll: ScrollDispatcher) { this.scrollingSubscription = this.scroll .scrolled() .subscribe((data: CdkScrollable) => { this.onWindowScroll(data); }); }
c) do something when scrolling, e.g. check the offset
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
Update Angular 9 :
Use import {ScrollingModule} from '@angular/cdk/scrolling'
, ScrollDispatchModule
is deprecated
I opened an Issue on @angular/material some time ago and they now expose the CdkScrollable
-Instance.
To use it, you need to access the MatSidenavContainer
using @ViewChild(MatSidenavContainer
. This instance has a public member scrollable
, which is the CdkScrollable
instance.
An example can be found here
Edit: As the example is not very complete and a few people are having difficulties implementing it, I'll write my own example here:
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:
- Don't use
<mat-sidenav-content>
. This tag is generated automatically and it has thecdkScrollable
directive attached to it. If you use<mat-sidenav-content>
in your own template, thescrollable
will be undefined. - Use
AfterViewInit
instead ofOnInit
. As much as I know,@ViewChild
is resolved inAfterViewInit
,OnInit
is probably too early.
Comments
Post a Comment