Angular-Material Sidenav cdkScrollable

时间:2017-11-28 10:09:17

标签: angular typescript scroll angular-material2 angular-cdk

Angular Material CDK提供了Directive CdkScrollable,可让您收听特定容器的ScrollEvent
我现在正在尝试访问默认添加的CdkScrollable MatSidenavContent 但是我的@ViewChild(CdkScrollable)和@ContentChild(CdkScrollable)总是未定义的。

我的Component看起来像这样:

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

生成的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>

自动生成的mat-sidenav-content Component使用CdkScrollable - 指令,我需要访问该指令。
我现在的问题是:
是否可以访问Directive,如果是,如何访问?

2 个答案:

答案 0 :(得分:11)

  1. 添加到您的应用模块导入:ScrollDispatchModule。
  2. 将cdkScrollable添加到mat-sidenav-content:
  3.   

    &lt; mat-sidenav-content cdkScrollable&gt; &LT; /垫sidenav含量&GT;

    1. 在根组件中:
    2. a)从@ angular / cdk / overlay注入ScrollDispatcher并订阅滚动:

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

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

      文档:https://material.angular.io/cdk/scrolling/api

答案 1 :(得分:4)

前段时间我在@ angular / material上打开了一个问题,他们现在公开了CdkScrollable - 实例。
要使用它,您需要使用MatSidenavContainer访问@ViewChild(MatSidenavContainer。此实例有一个公共成员scrollable,即CdkScrollable个实例 可以找到一个示例here

修改 由于示例不是很完整,并且有些人在实施它时遇到困难,我将在此处编写自己的示例:

<强> HTML

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

<强>打字稿:

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);
    }
}

重要

  1. 不要使用<mat-sidenav-content>。此标记是自动生成的,并且附加了cdkScrollable指令。如果您在自己的模板中使用<mat-sidenav-content>scrollable将是未定义的。
  2. 使用AfterViewInit代替OnInit。据我所知,@ViewChild已在AfterViewInit中解决,OnInit可能为时尚早。