web-dev-qa-db-fra.com

Comment créer un popup modal compatible avec Angular 4

Je veux pouvoir créer une fenêtre contextuelle qui chargera un certain composant Angular 4 du mien quand un bouton radio est sélectionné.

Il semble que les méthodes énumérées dans les réponses à cette question ne soient compatibles qu'avec Angular 2.

Je ne sais pas par où commencer et j'apprécierais toute aide!

19
Luca Guarro

Contrôle Dialogue de matériau angulaire , voici le Plunker

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<DialogResultExampleDialog>) {}
}
13
Madhu Ranjan

La réponse acceptée ajoute une grande dépendance à swat une mouche. Les boîtes de dialogue modales (et non modales) sont en grande partie le résultat d'une ou de deux classes CSS. Essayez cet exemple de "renommer ...":

1) Ecrivez le parent et le modal enfant comme si l'enfant n'était pas modal, mais juste un formulaire en ligne avec * ngIf attaché.

HTML parent qui utilise l'enfant <my-modal>:

<div>
    A div for {{name}}.
    <button type="button" (click)="showModal()">Rename</button>
    <my-modal *ngIf="showIt" [oldname]="name" (close)="closeModal($event)"></my-modal>
</div>

Classe parentale. Le décorateur @Component A été omis par souci de brièveté. (La propriété name appartient à la classe parente et existerait même si nous n'avions pas de formulaire pour le modifier.)

export class AppComponent {
    name = "old name";

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

}

Composant enfant à être modal. @Component Décorateur et importe à nouveau omis.

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

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

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

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

Child HTML avant de le modaliser.

<div>
    Rename {{oldname}}
    <input type="text" (change)="newname = $event.target.value;" />
    <button type="button" (click)="ok()">OK</button>
    <button type="button" (click)="cancel()">Cancel</button>
</div>

2) Voici le CSS pour enfant, mais il peut être placé dans une feuille de style globale pour être réutilisé dans toute votre application. C'est une classe unique appelée modal qui est destinée à un élément <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;
}

Mais la classe CSS modal CSS n'empêchera pas l'interaction avec la page située en dessous. (Cela crée donc techniquement un dialogue sans modèle.) Nous plaçons donc un overlay sous le modal pour absorber et ignorer l'activité de la souris. overlay est également destiné à un élément <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;
}

3) Utilisez modal et overlay dans le code HTML enfant.

<div class="modal">
    Rename {{oldname}}
    <input type="text" (change)="newname = $event.target.value;" />
    <button type="button" (click)="ok()">OK</button>
    <button type="button" (click)="cancel()">Cancel</button>
</div>
<div class="overlay"></div>

Et c'est tout. En gros 2 classes CSS et vous pouvez transformer n'importe quel composant en modal. En fait, vous pouvez afficher un composant en ligne ou sous forme de modal au moment de l'exécution en modifiant simplement l'existence de la classe CSS avec ngClass ou [class.modal]="showAsModalBoolean".

Vous pouvez modifier cela pour que l'enfant contrôle la logique d'affichage/masquage. Déplacez les fonctions * ngIf, showIt et show () dans l'enfant. Dans le parent, ajoutez @ViewChild(MyModalComponent) renameModal: MyModalComponent;, puis le parent peut impérativement appeler this.renameModal.show(this.name); et relier l'initialisation et les div au besoin.

Le modal enfant peut renvoyer des informations à la fonction d'un parent, comme indiqué ci-dessus, ou la méthode show() de l'enfant pourrait accepter un rappel ou renvoyer une promesse, selon le goût.

Deux choses à savoir:

this.renameModal.show(..); ne fonctionnera pas s'il y a un * ngIf sur <my-modal> car il n'existera pas pour exposer la fonction. * ngIf supprime le composant entier, la fonction show () et tout, utilisez donc [hidden] à la place si vous en avez besoin pour une raison quelconque.

Les modaux sur modaux auront des problèmes d'index z, car ils partagent tous le même index z. Cela peut être résolu avec [style.z-index]="calculatedValue" Ou similaire.

17
Ron Newcomb