Angular 2.0 e Diálogo Modal

Eu estou tentando encontrar alguns exemplos sobre como fazer um modal dialog de confirmação no Angular 2.0. Eu tenho usado o diálogo Bootstrap para o Angular 1.0 e não consigo encontrar nenhum exemplo na Web para o Angular 2.0. Eu também verifiquei documentos angulares 2.0 sem sorte.

Existe uma maneira de usar o diálogo Bootstrap com o Angular 2.0?

Obrigado !

  • Angular 2 e acima
  • Bootstrap css (animação é preservada)
  • NÃO JQuery
  • NÃO bootstrap.js
  • Suporta conteúdo modal personalizado (assim como a resposta aceita)
  • Suporte recentemente adicionado para vários modais em cima uns dos outros .

`

@Component({ selector: 'app-component', template: `   
header
Whatever content you like, form fields, anything
` }) export class AppComponent { } @Component({ selector: 'app-modal', template: ` ` }) export class ModalComponent { public visible = false; public visibleAnimate = false; public show(): void { this.visible = true; setTimeout(() => this.visibleAnimate = true, 100); } public hide(): void { this.visibleAnimate = false; setTimeout(() => this.visible = false, 300); } public onContainerClicked(event: MouseEvent): void { if ((event.target).classList.contains('modal')) { this.hide(); } } }

Para mostrar o cenário , você precisará de algo como este CSS:

 .modal { background: rgba(0,0,0,0.6); } 

O exemplo agora permite vários modais ao mesmo tempo . (veja o método onContainerClicked() ).

Para usuários Bootstrap 4 css , você precisa fazer 1 pequena alteração (porque um nome de class css foi atualizado a partir do Bootstrap 3). Esta linha: [ngClass]="{'in': visibleAnimate}" deve ser alterada para: [ngClass]="{'show': visibleAnimate}"

Para demonstrar, aqui está um plunkr

Aqui está um exemplo bastante decente de como você pode usar o modal Bootstrap dentro de um aplicativo Angular2 no GitHub .

A essência disso é que você pode envolver a boot do html e do jquery em um componente. Eu criei um componente modal reutilizável que permite acionar uma abertura usando uma variável de modelo.

       Hello World!    

Você só precisa instalar o pacote npm e registrar o módulo modal no seu módulo de aplicativo:

 import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal'; @NgModule({ imports: [Ng2Bs3ModalModule] }) export class MyAppModule {} 

Essa é uma abordagem simples que não depende de jquery ou de qualquer outra biblioteca, exceto Angular 2. O componente abaixo (errorMessage.ts) pode ser usado como uma exibição secundária de qualquer outro componente. É simplesmente um modal de bootstrap que está sempre aberto ou exibido. Sua visibilidade é governada pela instrução ngIf.

errorMessage.ts

 import { Component } from '@angular/core'; @Component({ selector: 'app-error-message', templateUrl: './app/common/errorMessage.html', }) export class ErrorMessage { private ErrorMsg: string; public ErrorMessageIsVisible: boolean; showErrorMessage(msg: string) { this.ErrorMsg = msg; this.ErrorMessageIsVisible = true; } hideErrorMsg() { this.ErrorMessageIsVisible = false; } } 

errorMessage.html

  

Este é um exemplo de controle pai (alguns códigos não relevantes foram omitidos por brevidade):

parent.ts

 import { Component, ViewChild } from '@angular/core'; import { NgForm } from '@angular/common'; import {Router, RouteSegment, OnActivate, ROUTER_DIRECTIVES } from '@angular/router'; import { OnInit } from '@angular/core'; import { Observable } from 'rxjs/Observable'; @Component({ selector: 'app-application-detail', templateUrl: './app/permissions/applicationDetail.html', directives: [ROUTER_DIRECTIVES, ErrorMessage] // Note ErrorMessage is a directive }) export class ApplicationDetail implements OnActivate { @ViewChild(ErrorMessage) errorMsg: ErrorMessage; // ErrorMessage is a ViewChild // yada yada onSubmit() { let result = this.permissionsService.SaveApplication(this.Application).subscribe(x => { x.Error = true; x.Message = "This is a dummy error message"; if (x.Error) { this.errorMsg.showErrorMessage(x.Message); } else { this.router.navigate(['/applicationsIndex']); } }); } } 

parent.html

  // your html... 

Eu uso o ngx-bootstrap para o meu projeto.

Você pode encontrar a demonstração aqui

O github está aqui

Como usar:

  1. Instale o ngx-bootstrap

  2. Importar para o seu módulo

 // RECOMMENDED (doesn't work with system.js) import { ModalModule } from 'ngx-bootstrap/modal'; // or import { ModalModule } from 'ngx-bootstrap'; @NgModule({ imports: [ModalModule.forRoot(),...] }) export class AppModule(){} 
  1. Modal estática simples
   

Agora disponível como pacote NPM

modalidade personalizada angular


@Stephen Paul continuação …

  • Angular 2 e acima Bootstrap css (animação é preservada)
  • NÃO JQuery
  • NÃO bootstrap.js
  • Suporta conteúdo modal personalizado
  • Suporte para vários modais em cima uns dos outros.
  • Modificado
  • Desativar rolagem quando o modal está aberto
  • O modal é destruído quando se navega.
  • Inicialização de conteúdo preguiçoso, que obtém ngOnDestroy (ed) quando o modal é encerrado.
  • Rolagem pai desativada quando modal é visível

Inicialização de conteúdo preguiçoso

Por quê?

Em alguns casos, você pode não querer modal para manter seu status depois de ter sido fechado, mas sim restaurado para o estado inicial.

Edição modal original

Passar o conteúdo diretamente para a visão, na verdade, gera a boot antes mesmo de o modal obtê-lo. O modal não tem como matar esse conteúdo, mesmo usando um wrapper *ngIf .

Solução

ng-template . ng-template não renderiza até que seja ordenado para fazer isso.

my-component.module.ts

 ... imports: [ ... ModalModule ] 

my-component.ts

          

modal.component.ts

 export class ModalComponent ... { @ContentChild('header') header: TemplateRef; @ContentChild('body') body: TemplateRef; @ContentChild('footer') footer: TemplateRef; ... } 

modal.component.html

 
...

Referências

Eu tenho que dizer que isso não teria sido possível sem a excelente documentação oficial e comunitária em torno da rede. Isso pode ajudar alguns de vocês também a entender melhor como o ng-template , *ngTemplateOutlet e @ContentChild funcionam.

https://angular.io/api/common/NgTemplateOutlet
https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/
https://medium.com/claritydesignsystem/ng-content-the-hidden-docs-96a29d70d11b
https://netbasal.com/understanding-viewchildren-contentchildren-and-querylist-in-angular-896b0c689f6e
https://netbasal.com/understanding-viewchildren-contentchildren-and-querylist-in-angular-896b0c689f6e

Solução completa de copiar e colar

modal.component.html

  

modal.component.ts

 /** * @Stephen Paul https://stackoverflow.com/a/40144809/2013580 * @zurfyx https://stackoverflow.com/a/46949848/2013580 */ import { Component, OnDestroy, ContentChild, TemplateRef } from '@angular/core'; @Component({ selector: 'app-modal', templateUrl: 'modal.component.html', styleUrls: ['modal.component.scss'], }) export class ModalComponent implements OnDestroy { @ContentChild('header') header: TemplateRef; @ContentChild('body') body: TemplateRef; @ContentChild('footer') footer: TemplateRef; public visible = false; public visibleAnimate = false; ngOnDestroy() { // Prevent modal from not executing its closing actions if the user navigated away (for example, // through a link). this.close(); } open(): void { document.body.style.overflow = 'hidden'; this.visible = true; setTimeout(() => this.visibleAnimate = true, 200); } close(): void { document.body.style.overflow = 'auto'; this.visibleAnimate = false; setTimeout(() => this.visible = false, 100); } onContainerClicked(event: MouseEvent): void { if ((event.target).classList.contains('modal')) { this.close(); } } } 

modal.module.ts

 import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ModalComponent } from './modal.component'; @NgModule({ imports: [ CommonModule, ], exports: [ModalComponent], declarations: [ModalComponent], providers: [], }) export class ModalModule { } 

Aqui está a minha implementação completa do componente de bootstrap angular2:

Eu suponho que no seu arquivo index.html principal (com tags e ) na parte inferior da tag você tem:

    

modal.component.ts:

 import { Component, Input, Output, ElementRef, EventEmitter, AfterViewInit } from '@angular/core'; declare var $: any;// this is very importnant (to work this line: this.modalEl.modal('show')) - don't do this (becouse this owerride jQuery which was changed by bootstrap, included in main html-body template): let $ = require('../../../../../node_modules/jquery/dist/jquery.min.js'); @Component({ selector: 'modal', templateUrl: './modal.html', }) export class Modal implements AfterViewInit { @Input() title:string; @Input() showClose:boolean = true; @Output() onClose: EventEmitter = new EventEmitter(); modalEl = null; id: string = uniqueId('modal_'); constructor(private _rootNode: ElementRef) {} open() { this.modalEl.modal('show'); } close() { this.modalEl.modal('hide'); } closeInternal() { // close modal when click on times button in up-right corner this.onClose.next(null); // emit event this.close(); } ngAfterViewInit() { this.modalEl = $(this._rootNode.nativeElement).find('div.modal'); } has(selector) { return $(this._rootNode.nativeElement).find(selector).length; } } let modal_id: number = 0; export function uniqueId(prefix: string): string { return prefix + ++modal_id; } 

modal.html:

  

E exemplo de uso no componente Editor de clientes: client-edit-component.ts:

 import { Component } from '@angular/core'; import { ClientService } from './client.service'; import { Modal } from '../common'; @Component({ selector: 'client-edit', directives: [ Modal ], templateUrl: './client-edit.html', providers: [ ClientService ] }) export class ClientEdit { _modal = null; constructor(private _ClientService: ClientService) {} bindModal(modal) {this._modal=modal;} open(client) { this._modal.open(); console.log({client}); } close() { this._modal.close(); } } 

client-edit.html:

 {{ bindModal(editModal) }} Som non-standart title Some contents   

É claro que o title , showClose , e são parâmetros / tags opcionais.

Eu recentemente bloguei sobre isso ..

Eu criei um serviço reutilizável que um componente pode ter injetado. Uma vez injetado, o componente pode se comunicar com o serviço se estiver em estado sujo e vinculado à navegação do roteador.

https://long2know.com/2017/01/angular2-menus-navigation-and-dialogs/ https://long2know.com/2017/01/angular2-dialogservice-exploring-bootstrap-part-2/

Verifique a checkbox de diálogo do ASUI que é criada no tempo de execução. Não há necessidade de esconder e mostrar lógica. Simplesmente serviço irá criar um componente em tempo de execução usando AOT ASUI NPM

tente usar o ng-window, ele permite que o desenvolvedor abra e controle completamente várias janelas em aplicativos de uma única página de maneira simples, No Jquery, No Bootstrap.

insira a descrição da imagem aqui

Configração Avilable

  • Janela Maxmize
  • Minimizar janela
  • Tamanho personalizado,
  • Posicionamento personalizado
  • a janela é arrastável
  • Bloquear janela pai ou não
  • Centralize a janela ou não
  • Passar valores para a janela de chield
  • Passar valores da janela chield para a janela pai
  • Ouvindo o fechamento da janela de chield na janela pai
  • Ouça o evento de redimensionamento com seu ouvinte personalizado
  • Abra com tamanho máximo ou não
  • Ativar e desativar o redimensionamento da janela
  • Ativar e desativar a maximização
  • Ativar e desativar a minimização