Угловой материал: как позиционировать MatDialog относительно элемента? - PullRequest
1 голос
/ 08 ноября 2019

Я разрабатываю угловое приложение. Я хочу открыть всплывающее диалоговое окно (экземпляр MatDialog), когда я нажимаю на кнопку. Я делаю это способом моей главной страницы следующим образом:

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, чтобы всплывающее окно отображалось в правом верхнем углу окна. Он сделал это хорошо. Через два дня я попытался расположить ее чуть ниже кнопки (верх: 52 пикселя), но она не работает, как если бы она сохраняла предыдущую позицию (в течение первых двух дней). Вы можете помочь мне

1 Ответ

1 голос
/ 08 ноября 2019

Всплывающее окно MatDialog может быть расположено относительно элемента. В приведенном ниже примере диалоговое окно открывается ниже и слева от нажатой кнопки на основе ограничивающего прямоугольника клиента кнопки. На элемент можно ссылаться через переменную ссылки шаблона.

Затем используйте 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
  }
}

...