Quiero ser capaz de crear una ventana emergente que cargará un determinado componente Angular 4 mío cuando se selecciona un botón de radio.
Parece que los métodos que aparecen en las respuestas a esta pregunta solo son compatibles con Angular 2.
No sé por dónde empezar y agradecería cualquier ayuda.
La respuesta aceptada añade una gran dependencia para matar una mosca. Los diálogos modales (y sin modelo) son en gran parte el resultado de una clase CSS o dos. Pruebe este "renombrar..." ejemplo:
HTML padre que utiliza <mi-modal>
hijo:
<div>
A div for {{name}}.
<button type="button" (click)="showModal()">Rename</button>
<my-modal *ngIf="showIt" [oldname]="name" (close)="closeModal($event)"></my-modal>
</div>
Clase padre. El decorador @Component
omitido por brevedad. (La propiedad name
pertenece a la clase padre y existiría aunque no tuviéramos un formulario para modificarla).
export class AppComponent {
name = "old name";
showIt = false;
showModal() {
this.showIt = true;
}
closeModal(newName: string) {
this.showIt = false;
if (newName) this.name = newName;
}
}
Componente hijo a modalizar. Decorador @Component
e importaciones omitidas de nuevo.
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);
}
}
HTML hijo antes de modalizarlo.
<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>
modal
y está pensada para un elemento <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;
}
Pero la clase CSS modal
no impide interactuar con la página que hay debajo. (Así que colocamos un overlay
debajo del modal para absorber e ignorar la actividad del ratón. overlay
también está pensado para un elemento <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;
}
modal
y el overlay
en el HTML hijo.<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>
Y eso'es todo. Básicamente 2 clases CSS y puedes hacer de cualquier componente un modal. De hecho puedes mostrar un componente en línea o como modal en tiempo de ejecución simplemente alterando la existencia de la clase CSS con ngClass
o [class.modal]="showAsModalBoolean"
.
Puedes alterar esto para que el hijo controle la lógica de mostrar/ocultar. Mueve las funciones *ngIf, showIt, y show() al hijo. En el padre añade @ViewChild(MyModalComponent) renameModal: MyModalComponent;
y entonces el padre puede imperativamente llamar a this.renameModal.show(this.name);
y re-cablear la inicialización y los divs contenedores como sea necesario.
El módulo hijo puede devolver información a una función padre como se muestra arriba, o el método show()
del módulo hijo puede aceptar una llamada de retorno o devolver una Promise, según se prefiera.
Dos cosas que hay que saber:
this.renameModal.show(..);
no funcionará si hay un ngIf en <my-modal>
porque para empezar no existirá para exponer la función. ngIf elimina todo el componente, función show() y todo, así que usa [hidden]
en su lugar si necesitas esto por alguna razón.
Modals-on-modals tendrán problemas de z-index ya que todos comparten el mismo z-index. Esto puede resolverse con `[style.z-index]="calculatedValue"o similar.
Compruebe Angular Material Dialogue, aquí está el 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>) {}
}