Angular Material CDKは、特定のコンテナのDirective
sをリッスンできる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を使用します。これにはアクセスする必要があります。
私の質問は次のとおりです。
そのDirective
にアクセスすることは可能ですか?
<mat-sidenav-content cdkScrollable> </ mat-sidenav-content>
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;
}
少し前に@ 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);
}
}
重要:
<mat-sidenav-content>
を使用しないでください。このタグは自動的に生成され、cdkScrollable
ディレクティブが添付されています。独自のテンプレートで<mat-sidenav-content>
を使用すると、scrollable
は未定義になります。AfterViewInit
の代わりにOnInit
を使用します。私が知っている限り、@ViewChild
はAfterViewInit
で解決されますが、OnInit
はおそらく早すぎるでしょう。