web-dev-qa-db-ja.com

角材Sidenav cdkScrollable

Angular Material CDKは、特定のコンテナのDirectivesをリッスンできるCdkScrollableScrollEventを提供します。
現在、デフォルトで追加されるCdkScrollableMatSidenavContentにアクセスしようとしています。
ただし、私の@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-contentComponentは自動的に生成され、CdkScrollable- Directiveを使用します。これにはアクセスする必要があります。
私の質問は次のとおりです。
そのDirectiveにアクセスすることは可能ですか?

10
Springrbua
  1. アプリモジュールインポートに追加:ScrollDispatchModule。
  2. CdkScrollableをmat-sidenav-contentに追加します。

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

  1. ルートコンポーネントで:

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

12
Sebastian Denis

少し前に@ angular/materialでIssueを開き、CdkScrollable- Instanceを公開しました。
これを使用するには、@ViewChild(MatSidenavContainerを使用してMatSidenavContainerにアクセスする必要があります。このインスタンスには、scrollableインスタンスであるパブリックメンバーCdkScrollableがあります。
例を見つけることができます こちら

Edit:この例は完全ではなく、少数の人々がそれを実装するのに苦労しているので、私はここに私自身の例を書きます:

[〜#〜] 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);
    }
}

重要

  1. <mat-sidenav-content>を使用しないでください。このタグは自動的に生成され、cdkScrollableディレクティブが添付されています。独自のテンプレートで<mat-sidenav-content>を使用すると、scrollableは未定義になります。
  2. AfterViewInitの代わりにOnInitを使用します。私が知っている限り、@ViewChildAfterViewInitで解決されますが、OnInitはおそらく早すぎるでしょう。
4
Springrbua