Angular Material:如何相对于元素定位 MatDialog? [英] Angular Material: How to position MatDialog relative to element?

查看:35
本文介绍了Angular Material:如何相对于元素定位 MatDialog?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 Angular 应用程序.我想在单击按钮时打开一个弹出对话框(MatDialog 的一个实例).我在我的主页的方法中这样做

I am developping an angular application. I want to open a dialog pop up (an instance of MatDialog) when I click on a button. I do it in a method of my main page as the following

    openDialog(event) {
      const element = document.getElementById(event.target.id);
      const jqelement = $(element);
      const position = jqelement.position(); // cache the position
      const bottom = position.top + jqelement.height();
      const dialogConfig = new MatDialogConfig();
      dialogConfig.disableClose = true;
      dialogConfig.autoFocus = true;
      dialogConfig.position = {
        top:  '' + bottom,
        right: '0'
      };
      dialogConfig.width = '50%' ;
      dialogConfig.height = '350px' ;
      console.log(dialogConfig);
      this.dialog.open(UserDialogComponent, dialogConfig);
    }

我希望它位于我单击的按钮的右侧和下方.一开始,我将 top: 0px 设置为弹出窗口显示在窗口的右上角.它做得很好.两天后,我试图将它放在按钮下方(顶部:52px),但它不起作用,就好像它保持以前的位置一样(在前两天).你能帮我吗

I want it to be positioned on the right and underneath the button that I click. At the beginning, I put top: 0px so the pop up displayed on the right up corner of the window. It did it well. After two days I tried to position it just below the button (top: 52px), but it does not work, just as if it keep the previous position (during the first two days). Can you help me

推荐答案

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
  }
}

这篇关于Angular Material:如何相对于元素定位 MatDialog?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆