Angular-Material Sidenav cdkScrollable
Angular-Material Sidenav cdkScrollable
Angular MaterialCDK 提供了Directive
CdkScrollable
,可以监听特定容器的ScrollEvent
。
我现在正在尝试访问默认添加的 MatSidenavContent
的 CdkScrollable
。
但是我的 @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
,如果可以,如何访问?
前段时间我在@angular/material 上开了一个 Issue,他们现在公开了 CdkScrollable
-Instance。
要使用它,您需要使用 @ViewChild(MatSidenavContainer
访问 MatSidenavContainer
。此实例有一个 public 成员 scrollable
,即 CdkScrollable
实例。
可以找到一个示例 here
编辑:
由于示例不是很完整,有些人在实现它时遇到困难,我将在这里编写自己的示例:
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
可能为时过早。
- 添加到您的应用模块导入:
ScrollDispatchModule
。
- 将
cdkScrollable
添加到您的 mat-sidenav-content
:
<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;
}
文档:https://material.angular.io/cdk/scrolling/api
更新 Angular 9 :
使用 import {ScrollingModule} from '@angular/cdk/scrolling'
,ScrollDispatchModule
已弃用
Angular MaterialCDK 提供了Directive
CdkScrollable
,可以监听特定容器的ScrollEvent
。
我现在正在尝试访问默认添加的 MatSidenavContent
的 CdkScrollable
。
但是我的 @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
,如果可以,如何访问?
前段时间我在@angular/material 上开了一个 Issue,他们现在公开了 CdkScrollable
-Instance。
要使用它,您需要使用 @ViewChild(MatSidenavContainer
访问 MatSidenavContainer
。此实例有一个 public 成员 scrollable
,即 CdkScrollable
实例。
可以找到一个示例 here
编辑: 由于示例不是很完整,有些人在实现它时遇到困难,我将在这里编写自己的示例:
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
可能为时过早。
- 添加到您的应用模块导入:
ScrollDispatchModule
。 - 将
cdkScrollable
添加到您的mat-sidenav-content
:
<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;
}
文档:https://material.angular.io/cdk/scrolling/api
更新 Angular 9 :
使用 import {ScrollingModule} from '@angular/cdk/scrolling'
,ScrollDispatchModule
已弃用