Как создать модальное всплывающее окно, совместимое с Angular 4

Я хочу иметь возможность создать всплывающее окно, которое будет загружать определенный мой компонент Angular 4 при выборе переключателя.

Похоже, что методы, перечисленные в ответах на этот вопрос [https://stackoverflow.com/questions/35400811/how-to-use-codes-to-open-a-modal-in-angular-2) совместимы только с Angular 2.

Я не уверен, с чего начать, и был бы признателен за любую помощь!

Комментарии к вопросу (4)

Принятый ответ добавляет большую зависимость от мухи. Модальные (и безмодели) диалоги в значительной степени являются результатом одного или двух классов CSS. Попробуйте это "переименовать..."пример:

  1. Напишите родительский и дочерний-модальный, как если бы ребенок вообще не был модальным, а просто встроенной формой с * ngIf.

Родительский HTML, который использует < my-modal >dild:

<div>
    A div for {{name}}.
    Rename

</div>

Родительский класс. Декоратор @ Component опущен для краткости. (Свойство name принадлежит родительскому классу и будет существовать, даже если у нас не будет формы для его изменения.)

export class AppComponent {
    name = "old name";

    showIt = false;
    showModal() {
        this.showIt = true;
    }
    closeModal(newName: string) {
        this.showIt = false;
        if (newName) this.name = newName;
    }

}

Детский, чтобы быть-модальным компонентом. @ Component декоратор и импорт снова опущены.

export class MyModalComponent {
    @Input() oldname = "";
    @Output() close = new EventEmitter();
    newname = "";

    ngOnInit() {
        // copy all inputs to avoid polluting them
        this.newname = this.oldname; 
    }

    ok() {
        this.close.emit(this.newname);
    }

    cancel() {
        this.close.emit(null);
    }
}

Детский HTML перед модальным его.

<div>
    Rename {{oldname}}
    <input type="text" (change)="newname = $event.target.value;" />
    OK
    Cancel
</div>
  1. Вот CSS для ребенка, но его можно поместить в глобальную таблицу стилей для повторного использования во всем приложении. Это один класс, называемый modal и предназначенный для элемента < div >.
.modal {
    /* detach from rest of the document */
    position: fixed;

    /* center */
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);

    /* ensure in front of rest of page -- increase as needed */
    z-index: 1001;

    /* visual illusion of being in front -- alter to taste */
    box-shadow: rgba(0,0,0,0.4) 10px 10px 4px;

    /* visual illusion of being a solid object -- alter to taste */
    background-color: lightblue;
    border: 5px solid darkblue;

    /* visual preference of don't crowd the contents -- alter to taste */
    padding: 10px;
}

Но «модальный» класс CSS не помешает взаимодействовать со страницей под ним. (Так что технически это создает диалог без моделей.) Таким образом, мы помещаем «наложение» под модалом, чтобы поглощать и игнорировать активность мыши. overlay также предназначен для элемента < div >.

.overlay {
    /* detach from document */
    position: fixed;

    /* ensure in front of rest of page except modal */
    z-index: 1000;

    /* fill screen to catch mice */
    top: 0;
    left: 0;
    width: 9999px;
    height: 9999px;

    /* dim screen 20% -- alter to taste */
    opacity: 0.2;
    background-color: black;
}
  1. Используйте modal и overlay в дочернем HTML .
<div class="modal">
    Rename {{oldname}}
    <input type="text" (change)="newname = $event.target.value;" />
    OK
    Cancel
</div>
<div class="overlay"></div>

И это все. В основном 2 класса CSS, и вы можете сделать любой компонент модальным. Фактически вы можете показать компонент в строке или как модальный во время выполнения, просто изменив существование класса CSS с помощью ngClass или [class.modal] = "showAsModalBoolean".

Вы можете изменить это, чтобы ребенок контролировал логику шоу / скрытия. Переместите функцию * ngIf, showIt и show () в дочернее устройство. В родительском списке добавьте @ViewChild (MyModalComponent) renameModal: MyModalComponent;, и тогда родитель может обязательно вызвать this.renameModal.show (this.name);и повторно подключить инициализацию и содержать дели по мере необходимости.

Ребенок-модальный может возвращать информацию в функцию родителя, как показано выше, или метод show ()ребенка может вместо этого принять обратный вызов или вернуть обещание по вкусу.

Две вещи, чтобы знать:

this.renameModal.show (..);не будет работать, если есть ngIf на < my-modal >, потому что он не будет существовать, чтобы раскрыть функцию с самого начала. ngIf удаляет весь компонент, функцию show () и все, поэтому используйте [hidden], если вам это нужно по какой-то причине.

У модалов на моделях будут проблемы с z-индексом, поскольку все они имеют один и тот же z-индекс. Это можно решить с помощью [style.z-index] = "calculatedValue"или аналогичного.

Комментарии (4)
Решение

Проверьте Angular Material Dialogue, вот [Plunker][2]

import {Component} from '@angular/core';
import {MdDialog, MdDialogRef} from '@angular/material';

@Component({
  selector: 'dialog-result-example',
  templateUrl: './dialog-result-example.html',
})
export class DialogResultExample {
  selectedOption: string;

  constructor(public dialog: MdDialog) {}

  openDialog() {
    let dialogRef = this.dialog.open(DialogResultExampleDialog);
    dialogRef.afterClosed().subscribe(result => {
      this.selectedOption = result;
    });
  }
}

@Component({
  selector: 'dialog-result-example-dialog',
  templateUrl: './dialog-result-example-dialog.html',
})
export class DialogResultExampleDialog {
  constructor(public dialogRef: MdDialogRef) {}
}

[2]: https://plnkr.co/edit/Dh9INs7QZPatSyhHywJc?р = предварительный просмотр

Комментарии (9)