[Angular] Overlay CDK

Some basic exmaple on Doc: https://material.angular.io/cdk/overlay/overview

 

复制代码
<!-- This button triggers the overlay and is it's origin -->
<button (click)="isOpen = !isOpen" type="button" cdkOverlayOrigin #trigger="cdkOverlayOrigin">
  {{isOpen ? "Close" : "Open"}}
</button>

<!-- This template displays the overlay content and is connected to the button -->
<ng-template
  cdkConnectedOverlay
  [cdkConnectedOverlayOrigin]="trigger"
  [cdkConnectedOverlayOpen]="isOpen"
>
  <ul class="example-list">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
</ng-template>
复制代码

 

Positioning

[cdkConnectedOverlayPositions]="positions"
复制代码
import {
  Component,
  OnInit,
  ChangeDetectionStrategy,
  ViewChild,
  ElementRef,
} from '@angular/core';
import { FocusMonitor } from '@angular/cdk/a11y';
import {
  CdkConnectedOverlay,
  ConnectedPosition,
  ScrollStrategyOptions,
  ScrollStrategy,
} from '@angular/cdk/overlay';
import { OverlayReference } from '@angular/cdk/overlay/overlay-reference';
...

@Component({
...
})
export class DropDownSearchComponent implements OnInit {

  positions: ConnectedPosition[] = [
    {
      originX: 'center',
      originY: 'bottom',
      overlayX: 'center',
      overlayY: 'top',
      offsetY: -21,
    },
    {
      originX: 'center',
      originY: 'top',
      overlayX: 'center',
      overlayY: 'bottom',
      panelClass: 'no-enogh-space-at-bottom',
    },
  ];

} 
复制代码

We have defined two Postions:

1. Center aligned. Overlay stay bottom

2. Center aligned. Overlay stay on top, if not enough space at bottom

Basiclly it will go though each position in array, apply it if previous position has not enough space for showing.

 

Creating Overlay and define position

复制代码
import {
  ConnectedPosition,
  Overlay,
  OverlayPositionBuilder,
} from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';

@Component({
...
})
export class AppComponent implements OnInit {

  @ViewChild(DropDownSearchComponent, { read: ElementRef, static: true })
  dropdown;

createDialog() {
    const overlayRef = this.overly.create({
      hasBackdrop: true,
      positionStrategy: this.positionBuilder
        .global()
        .centerHorizontally()
        .centerVertically(),
      // .flexibleConnectedTo(this.dropdown)
      // .withPositions([
      //   {
      //     // here, top-left of the overlay is connected to bottom-left of the origin;
      //     // of course, you can change this object or generate it dynamically;
      //     // moreover, you can specify multiple objects in this array for CDK to find the most suitable option
      //     originX: 'center',
      //     originY: 'bottom',
      //     overlayX: 'center',
      //     overlayY: 'top',
      //   } as ConnectedPosition,
      // ])
      // .withPush(false),
    });
    const dialogPortal = new ComponentPortal(DialogComponent);
    overlayRef.attach(dialogPortal);
    overlayRef.backdropClick().subscribe(() => overlayRef.detach());
  }
}
复制代码

 

you can have

1. global position: for example center the overlay

2. flex position: attach to one origin

 

Scolling

[cdkConnectedOverlayScrollStrategy]="scrollStrategy"
复制代码
import {
  CdkConnectedOverlay,
  ConnectedPosition,
  ScrollStrategyOptions,
  ScrollStrategy,
} from '@angular/cdk/overlay';

@Component({
...
})
export class DropDownSearchComponent implements OnInit {

  scrollStrategy: ScrollStrategy;

  constructor(
    private focusMonitor: FocusMonitor,
    private scrollStrategies: ScrollStrategyOptions
  ) {}

    // this.scrollStrategy = new ConfirmScrollStrategy(this.inputEl);
// this.scrollStrategy = this.scrollStrategies.none()
// this.scrollStrategy = this.scrollStrategies.block(); // this.scrollStrategy = this.scrollStrategies.close({ // threshold: 50, // }); this.scrollStrategy = this.scrollStrategies.reposition(); .. } class ConfirmScrollStrategy implements ScrollStrategy { _overlay: OverlayReference; constructor(private inputRef: ElementRef) {} attach(overlayRef: OverlayReference) { this._overlay = overlayRef; } enable() { document.addEventListener('scroll', this.scrollListener); } disable() { document.removeEventListener('scroll', this.scrollListener); } private scrollListener = () => { if (confirm('The overlay will be closed. Procced?')) { this._overlay.detach(); this.inputRef.nativeElement.blur(); return; } this._overlay.updatePosition(); }; }
复制代码

There are 4 built-in srolling types:

1. none: Overlay stay where it was, no matter how you scroll your app

2. block: App cannot scroll at all

3. close: close the overlay once over the threhold

4. reposition: follow the origin when srcolling

 

You can also build a custom scrolling type as the one ´ConfirmScrollStrategy´.

 

Misc

Breakpoint

复制代码
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
..

  constructor(
    ..
    private breakpointObserver: BreakpointObserver
  ) {}

  ngOnInit(): void {
    if (this.breakpointObserver.isMatched('(max-width: 600px)')) {
      console.info('The screen width is less than 600px');
    }
    this.isWideScreen$ = this.breakpointObserver
      .observe([Breakpoints.HandsetLandscape])
      .pipe(map(({ matches }) => matches));
  }
复制代码

 

focusMonitor

复制代码
import { FocusMonitor } from '@angular/cdk/a11y';

  constructor(
    private focusMonitor: FocusMonitor,

  ) {}

    this.isPanelVisible$ = this.focusMonitor.monitor(this.inputEl).pipe()

}
复制代码

 

Listen to keyboard event for Overlay

复制代码
import { ESCAPE } from '@angular/cdk/keycodes';

@ViewChild(CdkConnectedOverlay, { static: true }) private connectedOverlay: CdkConnectedOverlay; const onEscClick$ = this.connectedOverlay.overlayKeydown.pipe( filter(({ keyCode }) => { return keyCode === ESCAPE; }) );
复制代码

 

More directives

复制代码
<ng-template
  cdkConnectedOverlay
  cdkConnectedOverlayHasBackdrop
  cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop"
  [cdkConnectedOverlayScrollStrategy]="scrollStrategy"
  [cdkConnectedOverlayOrigin]="originOverlay"
  [cdkConnectedOverlayOpen]="showPanel$ | async"
  [cdkConnectedOverlayPositions]="positions"
>
复制代码

 

Code:

https://github.com/DMezhenskyi/angular-cdk-lessons

videos:

https://www.youtube.com/watch?v=2pS9bYtsBRo

posted @   Zhentiw  阅读(346)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2020-09-30 [Typescript] “keyof”, Generics and Lookup Types
2020-09-30 [TypeScript] “typeof” Type Queries
2020-09-30 [Javascript] Broadcaster + Operator + Listener pattern -- 4. Concat
2020-09-30 [Javascript] Broadcaster + Operator + Listener pattern -- 3 Stop with condition
2020-09-30 [Typescript] Typing “this” and “noImplicitThis”
2017-09-30 [Javascript AST] 4. Continue: Report ESLint error
2017-09-30 [RxJS] Learn How To Use RxJS 5.5 Beta 2
点击右上角即可分享
微信分享提示