简体   繁体   English

Angular-Material Sidenav cdkScrollable

[英]Angular-Material Sidenav cdkScrollable

The Angular Material CDK provides a Directive CdkScrollable , which allows you to listen to ScrollEvent s of a specific container. Angular Material CDK 提供了一个Directive CdkScrollable ,它允许你监听特定容器的ScrollEvent
I am now trying to access the CdkScrollable of the MatSidenavContent , which is added by default.我现在正在尝试访问默认添加的CdkScrollableMatSidenavContent
However my @ViewChild(CdkScrollable) and @ContentChild(CdkScrollable) are always undefined.但是我的@ViewChild(CdkScrollable)@ContentChild(CdkScrollable)总是未定义的。

My Component looks something like this:我的Component看起来像这样:

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

The resulting DOM looks something like this:生成的 DOM 如下所示:

<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>

The mat-sidenav-content Component , which is generated automatically, uses a CdkScrollable -Directive, which I need to access. mat-sidenav-content Component是自动生成的,它使用我需要访问的CdkScrollable -Directive。
My question is now:我现在的问题是:
Is it possible to access that Directive and if so, how?是否可以访问该Directive ,如果可以,如何访问?

  1. Add to your app module imports: ScrollDispatchModule .添加到您的应用程序模块导入: ScrollDispatchModule
  2. Add cdkScrollable to your mat-sidenav-content :cdkScrollable添加到您的mat-sidenav-content

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

  1. In your root component:在您的根组件中:

a) inject ScrollDispatcher from @angular/cdk/overlay and subscribe to scrolling: a) 从@angular/cdk/overlay注入ScrollDispatcher并订阅滚动:

constructor(public scroll: ScrollDispatcher) {

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

c) do something when scrolling, eg check the offset c) 滚动时做一些事情,例如检查偏移量

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文档: https : //material.angular.io/cdk/scrolling/api

Update Angular 9 :更新 Angular 9:

Use import {ScrollingModule} from '@angular/cdk/scrolling' , ScrollDispatchModule is deprecated使用import {ScrollingModule} from '@angular/cdk/scrolling' ,不推荐使用ScrollDispatchModule

I opened an Issue on @angular/material some time ago and they now expose the CdkScrollable -Instance.前段时间我在@angular/material 上打开了一个问题,他们现在公开了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.要使用它,你需要访问MatSidenavContainer使用@ViewChild(MatSidenavContainer 。这个实例有一个公共的成员scrollable ,这是CdkScrollable实例。
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 : 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. Don't use <mat-sidenav-content> .不要使用<mat-sidenav-content> This tag is generated automatically and it has the cdkScrollable directive attached to it.这个标签是自动生成的,并且附加了cdkScrollable指令。 If you use <mat-sidenav-content> in your own template, the scrollable will be undefined.如果您在自己的模板中使用<mat-sidenav-content> ,则可scrollable将是未定义的。
  2. Use AfterViewInit instead of OnInit .使用AfterViewInit而不是OnInit As much as I know, @ViewChild is resolved in AfterViewInit , OnInit is probably too early.据我所知, @ViewChildAfterViewInit解决, OnInit可能为时过早。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM