且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Angular Material:如何相对于元素定位 MatDialog?

更新时间:2022-05-20 02:42:01

MatDialog 弹出窗口可以相对于元素定位.在下面的示例中,对话框根据按钮的边界客户端矩形在单击按钮的下方和左侧打开.可以通过模板引用变量引用该元素.

The MatDialog popup may be positioned relative to an element. In the example below, the dialog is opened below and to the left of the clicked button based on the button's bounding client rectangle. The element may be referenced via a template reference variable.

然后使用MatDialogRef 方法updatePosition.

<button #myButton></button>

主要组件

import { AfterViewInit, Component, ElementRef, OnDestroy, ViewChild } from '@angular/core'
import { DialogService } from './dialog.service.ts'

@Component({
  selector: 'main-component',
  templateUrl: 'main.component.html',
  styleUrls: ['main.component.css']
})
export class MainComponent implements AfterViewInit, OnDestroy {
  @ViewChild('myButton', { static: false }) public myButtonRef: ElementRef

  constructor(private dialogService: DialogService) {}

  public openDialog() {
    dialogRef = this.dialogService.openDialog({
      positionRelativeToElement: this.myButtonRef,
      has_backdrop: true
    })

    this.dialogRef.afterClosed().subscribe(
      () => {
        ...
        this.dialogRef = null
      }
    )
  }
}

dialog.component.ts

import { Component, ElementRef, Inject, OnInit } from '@angular/core'
import { MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'


@Component({
  selector: 'dialog-component',
  templateUrl: './dialog.component.html',
  styleUrls: ['./dialog.component.css']
})
export class DialogComponent implements OnInit {
  private positionRelativeToElement: ElementRef

  constructor(public dialogRef: MatDialogRef<DialogComponent>,
    @Inject(MAT_DIALOG_DATA) public options: { positionRelativeToElement: ElementRef }) {

    this.positionRelativeToElement = options.positionRelativeToElement
  }

  ngOnInit() {
    const matDialogConfig = new MatDialogConfig()
    const rect: DOMRect = this.positionRelativeToElement.nativeElement.getBoundingClientRect()

    matDialogConfig.position = { right: `10px`, top: `${rect.bottom + 2}px` }
    this.dialogRef.updatePosition(matDialogConfig.position)
  }
}

dialog.service.ts

import { ElementRef, Injectable } from '@angular/core'
import { MatDialog, MatDialogRef } from '@angular/material'

import { DialogComponent } from './dialog.component'


/**
 * Service to create modal dialog windows.
 */
@Injectable({
  providedIn: 'root'
})
export class DialogService {

  constructor(public dialog: MatDialog) { }

  public openDialog({ position_relative_to_element, user,
    has_backdrop = false, height = '135px', width = '290px' }:
    {
      positionRelativeToElement: ElementRef, hasBackdrop?: boolean,
      height?: string, width?: string
    }): MatDialogRef<DialogComponent> {

    const dialogRef: MatDialogRef<DialogComponent> =
      this.dialog.open(DialogComponent, {
        hasBackdrop: hasBackdrop,
        height: height,
        width: width,
        data: { positionRelativeToElement: positionRelativeToElement }
      })
    return dialogRef
  }
}