Невозможно нажать на диалоговое окно подтверждения PrimeNG, экран заблокирован

Этот код когда-то работал, так что я думаю, что меня зацепило обновление PrimeNG, которое что-то сломало для меня. То, что когда-то было полезным диалоговым окном подтверждения, теперь скрыто за серой маской щелчка, которая делает все на экране неприкосновенным:

заблокированный диалог подтверждения

HTML для этих двух диалогов выглядит так:

<p-dialog header="Save Location" [modal]="true" [(visible)]="showSaveDialog" width="350" height="190">
  <div style="height: 60px;">
    Save location as:&nbsp;
    <ks-dropdown #saveNameDropdown [(ngModel)]="selectedName" [options]="saveDialogNames" [editable]="true" [style]="{width: '200px'}"></ks-dropdown>
    <br><br><p-checkbox [(ngModel)]="makeDefault" binary="true" label="Make this the default location"></p-checkbox>
  </div>
  <p-footer>
    <div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
      <button type="button" pButton icon="far fa-window-close" (click)="showSaveDialog=false" label="Cancel"></button>
      <button type="button" pButton icon="fas fa-check" (click)="doSave()" label="OK" [disabled]="!selectedName.trim()"></button>
    </div>
  </p-footer>
  <p-confirmDialog header="Same location name in use" icon="fas fa-question-circle" width="400"></p-confirmDialog>
</p-dialog>

И код, который запускает диалог подтверждения, выглядит так:

if (_.find(this.app.locations, {name: this.selectedName })) {
  this.confirmationService.confirm({
    message: `Are you sure you want to replace the existing "${this.selectedName}"?`,
    accept: () => this.completeSave()
  });
}

Я пытался установить z-index диалога выше, чем ui-dialog-maskdiv это появляется, но это не помогло.

Я мог бы быть в состоянии взломать некоторое исправление, ища DOM для оскорбительного ui-dialog-mask, но я бы предпочел не делать этого, если кто-то еще может понять, что я могу делать неправильно, или у меня есть лучшее решение.

3 ответа

Решение

Я считаю, что это ошибка в диалоге primeng / подтверждения. Некоторые люди предложили использовать appendTo = 'body', чтобы исправить это, однако это вызвало еще одну ошибку, поскольку код добавляет диалог div только к телу, а не ко всему нативному элементу. Вот моя работа, которая, кажется, работает.

Перейдите в ClientApp/node_modules/primeng/components/ verifydialog / verifydialog.js

строка 73 измените его на: document.body.appendChild(this.container); to: document.body.appendChild(this.el.nativeElement);

Убедитесь, что вы используете appendTo = 'body'

Приветствия.

Я решил эту проблему, добавив appendTo="body" в диалоговом окне подтверждения, как показано ниже:

 <p-confirmDialog header="Confirmation" icon="pi pi-exclamation-triangle" appendTo="body"></p-confirmDialog>

Я столкнулся с той же проблемой. Я нашел основную причину того, что мы использовали несколько ConfirmDialog.
Пример: использование углового JS
- В файле app.component.html:

<app-home></app-home>
<p-confirmDialog header="Confirmation" icon="pi pi-exclamation-triangle" width="425" global="false"></p-confirmDialog>

- В файле home.component.html:

<p-confirmDialog header="Confirmation" icon="pi pi-exclamation-triangle" width="425" global="false"></p-confirmDialog>

Поэтому, если мы обработаем файл компонента (app.component.ts) следующим образом:

 this.confirmationService.confirm({
      header: 'Confirmation',
      message: `Are you sure?`,
      accept: () => {
       // handle except
      },
      reject: () => {
       // handle reject
      }
 });

Этот кусок кода вызовет оба ConfirmDialogs выше

Решение:

Удалить один из двух ConfirmDialog. ConfirmDialog внутреннего компонента лучше. (В моем примере: ConfirmDialog из home.component.html должен быть удален.)

Из-за отсутствия лучшего ответа на данный момент я собираюсь сделать следующее:

  setTimeout(() => {
    const masks = document.getElementsByClassName('ui-dialog-mask');

    if (masks && masks.length > 0)
      (masks[masks.length - 1] as HTMLElement).style.zIndex = 'auto';
  });

Это выполняется сразу после this.confirmationService.confirm(... выше. Это не идеальное решение, потому что оно не помещает маску между нижним диалоговым окном и верхним диалоговым окном, оно просто приводит к тому, что оба диалоговых окна открываются, а все остальное ниже двух диалоговых окон маскируется.

Однако гораздо лучше, чем блокировка приложения.

ОБНОВЛЕНИЕ: новое решение, основанное на ответе user860214, как код, добавленный внизу моего проекта app.module.ts файл:

// TODO: Hack to be removed when bug is fixed in PrimeNG.
import { ConfirmDialog } from 'primeng/confirmdialog';

ConfirmDialog.prototype.appendContainer = function(): void {
  if (this.appendTo) {
    if (this.appendTo === 'body')
      document.body.appendChild(this.el.nativeElement);
    else
      this.domHandler.appendChild(this.container, this.appendTo);
  }
};
Другие вопросы по тегам