typescript Angular-Material Sidenav cdkScrollable

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47528852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:04:42  来源:igfitidea点击:

Angular-Material Sidenav cdkScrollable

angulartypescriptscrollangular-material2angular-cdk

提问by Springrbua

The Angular Material CDK provides a DirectiveCdkScrollable, which allows you to listen to ScrollEvents of a specific container.
I am now trying to access the CdkScrollableof the MatSidenavContent, which is added by default.
However my @ViewChild(CdkScrollable) and @ContentChild(CdkScrollable) are always undefined.

Angular Material CDK 提供了一个DirectiveCdkScrollable,它允许您收听ScrollEvent特定容器的 s。
我现在想访问CdkScrollableMatSidenavContent,这是默认添加。
但是我的 @ViewChild(CdkScrollable) 和 @ContentChild(CdkScrollable) 始终未定义。

My Componentlooks 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-contentComponent, which is generated automatically, uses a CdkScrollable-Directive, which I need to access.
My question is now:
Is it possible to access that Directiveand if so, how?

mat-sidenav-contentComponent,这是自动生成的,采用的是CdkScrollable-Directive,我需要访问。
我现在的问题是:
是否可以访问它Directive,如果可以,如何访问?

采纳答案by Springrbua

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 MatSidenavContainerusing @ViewChild(MatSidenavContainer. This instance has a public member scrollable, which is the CdkScrollableinstance.
An example can be found here

前段时间我在@angular/material 上打开了一个问题,他们现在公开了CdkScrollable-Instance。
要使用它,您需要访问MatSidenavContainerusing @ViewChild(MatSidenavContainer。这个实例有一个公共成员scrollable,也就是CdkScrollable实例。
一个例子可以在这里找到

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>. This tag is generated automatically and it has the cdkScrollabledirective attached to it. If you use <mat-sidenav-content>in your own template, the scrollablewill be undefined.
  2. Use AfterViewInitinstead of OnInit. As much as I know, @ViewChildis resolved in AfterViewInit, OnInitis probably too early.
  1. 不要使用<mat-sidenav-content>. 这个标签是自动生成的,并且cdkScrollable附有指令。如果您<mat-sidenav-content>在自己的模板中使用,scrollable则将是未定义的。
  2. 使用AfterViewInit代替OnInit。据我所知,@ViewChild在 中解决AfterViewInitOnInit可能还为时过早。

回答by Sebastian Denis

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

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

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

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

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, e.g. 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', ScrollDispatchModuleis deprecated

使用import {ScrollingModule} from '@angular/cdk/scrolling',ScrollDispatchModule已弃用