Dialogue angulaire 2.0 et Modal

J'essaie de trouver quelques exemples sur la façon de faire une boîte de dialogue modale de Confirmation dans Angular 2.0. J'ai utilisé Bootstrap dialog pour Angular 1.0 et incapable de trouver des exemples dans le web pour Angular 2.0. J'ai également vérifié les documents angular 2.0 sans succès.

Existe-t-il un moyen d'utiliser la boîte de dialogue Bootstrap avec Angular 2.0?

Merci!

119
demandé sur Rohit Sharma 2015-12-29 17:57:04

9 réponses

  • angulaire 2 et plus
  • Bootstrap css (l'animation est préservée)
  • PAS de JQuery
  • PAS de bootstrap.js
  • prend en charge contenu modal personnalisé (tout comme la réponse acceptée)
  • récemment ajouté le support pour plusieurs modaux les uns sur les autres .

`

@Component({
  selector: 'app-component',
  template: `
  <button type="button" (click)="modal.show()">test</button>
  <app-modal #modal>
    <div class="app-modal-header">
      header
    </div>
    <div class="app-modal-body">
      Whatever content you like, form fields, anything
    </div>
    <div class="app-modal-footer">
      <button type="button" class="btn btn-default" (click)="modal.hide()">Close</button>
      <button type="button" class="btn btn-primary">Save changes</button>
    </div>
  </app-modal>
  `
})
export class AppComponent {
}

@Component({
  selector: 'app-modal',
  template: `
  <div (click)="onContainerClicked($event)" class="modal fade" tabindex="-1" [ngClass]="{'in': visibleAnimate}"
       [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <ng-content select=".app-modal-header"></ng-content>
        </div>
        <div class="modal-body">
          <ng-content select=".app-modal-body"></ng-content>
        </div>
        <div class="modal-footer">
          <ng-content select=".app-modal-footer"></ng-content>
        </div>
      </div>
    </div>
  </div>
  `
})
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 ((<HTMLElement>event.target).classList.contains('modal')) {
      this.hide();
    }
  }
}

Pour afficher la toile de fond , Vous aurez besoin de quelque chose comme ceci CSS:

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

L'exemple permet maintenant de plusieurs auxiliaires modaux en même temps . (voir la méthode onContainerClicked()).

Pour les utilisateurs CSS Bootstrap 4 , vous devez effectuer 1 Modification mineure (car un nom de classe CSS a été mis à jour à partir de Bootstrap 3). Cette ligne: [ngClass]="{'in': visibleAnimate}" doit être remplacé par: [ngClass]="{'show': visibleAnimate}"

Démontrer, voici une plunkr

191
répondu Stephen Paul 2017-07-16 06:01:49

Voici un exemple assez décent de la façon dont vous pouvez utiliser le modal Bootstrap dans une application Angular2 sur GitHub .

L'essentiel est que vous pouvez envelopper l'initialisation de bootstrap html et jquery dans un composant. J'ai créé un composant modal réutilisable qui vous permet de déclencher un open en utilisant une variable de modèle.

<button type="button" class="btn btn-default" (click)="modal.open()">Open me!</button>

<modal #modal>
    <modal-header [show-close]="true">
        <h4 class="modal-title">I'm a modal!</h4>
    </modal-header>
    <modal-body>
        Hello World!
    </modal-body>
    <modal-footer [show-default-buttons]="true"></modal-footer>
</modal>

Il vous suffit d'installer le package npm et d'enregistrer le module modal dans votre module app:

import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal';

@NgModule({
    imports: [Ng2Bs3ModalModule]
})
export class MyAppModule {}
55
répondu Douglas Ludlow 2017-03-03 16:25:15

C'est une approche simple qui ne dépend pas de jquery ou de toute autre bibliothèque sauf Angular 2. Le composant ci-dessous (errorMessage.ts) peut être utilisé comme vue enfant de n'importe quel autre composant. C'est simplement un modal bootstrap qui est toujours ouvert ou affiché. Sa visibilité est régie par la déclaration 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

<div *ngIf="ErrorMessageIsVisible" class="modal fade show in danger" id="myModal" role="dialog">
    <div class="modal-dialog">

        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Error</h4>
            </div>
            <div class="modal-body">
                <p>{{ErrorMsg}}</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" (click)="hideErrorMsg()">Close</button>
            </div>
        </div>
    </div>
</div>

Ceci est un exemple de contrôle parent (un code non pertinent a été omis pour brièveté):

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

<app-error-message></app-error-message>
// your html...
45
répondu Sam 2016-05-24 00:20:32

J'utilise ngx-bootstrap pour mon projet.

Vous pouvez trouver la démo ici

Le github est ici

Comment utiliser:

  1. Installez ngx-bootstrap

  2. Importation de votre module

// 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 statique Simple
<button type="button" class="btn btn-primary" (click)="staticModal.show()">Static modal</button>
<div class="modal fade" bsModal #staticModal="bs-modal" [config]="{backdrop: 'static'}"
tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
   <div class="modal-content">
      <div class="modal-header">
         <h4 class="modal-title pull-left">Static modal</h4>
         <button type="button" class="close pull-right" aria-label="Close" (click)="staticModal.hide()">
         <span aria-hidden="true">&times;</span>
         </button>
      </div>
      <div class="modal-body">
         This is static modal, backdrop click will not close it.
         Click <b>&times;</b> to close modal.
      </div>
   </div>
</div>
</div>
7
répondu Frank Nguyen 2017-06-15 11:43:31

Maintenant disponible en tant que paquet npm

Angulaire-custom-modal


@ Stephen Paul Suite ...

  • Angular 2 et up Bootstrap css (l'animation est préservée)
  • Pas de JQuery
  • PAS de bootstrap.js
  • prend en charge le contenu modal personnalisé
  • prise en charge de plusieurs modals sur le dessus de chacun autre.
  • Moduralisé
  • Désactiver le défilement quand modal est ouvert
  • Modal est détruit lors de la navigation loin.
  • initialisation de contenu paresseux, qui obtient ngOnDestroy (ed) lorsque le modal est sorti.
  • Parent de défilement désactivé lorsque le modal est visible

Initialisation de contenu paresseux

Pourquoi?

Dans certains cas, vous pouvez ne pas vouloir modal pour conserver son statut après avoir été fermé, mais plutôt restauré à l'état initial.

Problème modal Original

Passer le contenu directement dans la vue génère réellement initialise avant même que le modal l'obtient. Le modal n'a pas de moyen de tuer un tel contenu même si vous utilisez un wrapper *ngIf.

Solution

ng-template. ng-template ne rend pas jusqu'à ce que ordonné de faire si.

Mon composant.module.ts

...
imports: [
  ...
  ModalModule
]

Mon composant.ts

<button (click)="reuseModal.open()">Open</button>
<app-modal #reuseModal>
  <ng-template #header></ng-template>
  <ng-template #body>
    <app-my-body-component>
      <!-- This component will be created only when modal is visible and will be destroyed when it's not. -->
    </app-my-body-content>
    <ng-template #footer></ng-template>
</app-modal>

Modal.composant.ts

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

Modal.composant.html

<div ... *ngIf="visible">
  ...
  <div class="modal-body">
    ng-container *ngTemplateOutlet="body"></ng-container>
  </div>

Références à

Je dois dire que cela n'aurait pas été possible sans l'excellente documentation officielle et communautaire autour du net. Il pourrait aider certains d'entre vous aussi pour mieux comprendre comment ng-template, *ngTemplateOutlet et @ContentChild travail.

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

Plein copier-coller solution

Modal.composant.html

<div
  (click)="onContainerClicked($event)"
  class="modal fade"
  tabindex="-1"
  [ngClass]="{'in': visibleAnimate}"
  [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}"
  *ngIf="visible">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <ng-container *ngTemplateOutlet="header"></ng-container>
        <button class="close" data-dismiss="modal" type="button" aria-label="Close" (click)="close()">×</button>
      </div>
      <div class="modal-body">
        <ng-container *ngTemplateOutlet="body"></ng-container>
      </div>
      <div class="modal-footer">
        <ng-container *ngTemplateOutlet="footer"></ng-container>
      </div>
    </div>
  </div>
</div>

Modal.composant.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<any>;
  @ContentChild('body') body: TemplateRef<any>;
  @ContentChild('footer') footer: TemplateRef<any>;

  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 ((<HTMLElement>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 { }
7
répondu zurfyx 2017-10-30 12:56:55

Voici mon implémentation complète du composant modal Bootstrap angular2:

Je suppose que dans votre index principal.fichier html (avec les balises <html> et <body>) en bas de la balise <body> Vous avez:

  <script src="assets/js/jquery-2.1.1.js"></script>
  <script src="assets/js/bootstrap.min.js"></script>

Modal.composant.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<any> = 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:

<div class="modal inmodal fade" id="{{modal_id}}" tabindex="-1" role="dialog"  aria-hidden="true" #thisModal>
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header" [ngClass]="{'hide': !(has('mhead') || title) }">
                <button *ngIf="showClose" type="button" class="close" (click)="closeInternal()"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                <ng-content select="mhead"></ng-content>
                <h4 *ngIf='title' class="modal-title">{{ title }}</h4>
            </div>
            <div class="modal-body">
                <ng-content></ng-content>
            </div>

            <div class="modal-footer" [ngClass]="{'hide': !has('mfoot') }" >
                <ng-content select="mfoot"></ng-content>
            </div>
        </div>
    </div>
</div>

Et exemple d'utilisation dans le composant éditeur client: client-modifier-composant.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-modifier.html:

<modal [title]='"Some standard title"' [showClose]='true' (onClose)="close()" #editModal>{{ bindModal(editModal) }}
    <mhead>Som non-standart title</mhead>
    Some contents
    <mfoot><button calss='btn' (click)="close()">Close</button></mfoot>
</modal>

, bien sûr title, showClose, <mhead> et <mfoot> ar en option paramètres/tags.

4
répondu Kamil Kiełczewski 2017-07-12 06:17:48

J'ai récemment blogué à ce sujet ..

J'ai créé un service réutilisable qu'un composant peut avoir injecté. Une fois injecté, le composant peut communiquer au service s'il est dans un état sale et s'attacher à la navigation du routeur.

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

2
répondu long2know 2017-01-25 14:38:15

Vérifiez la boîte de dialogue ASUI qui crée à l'exécution. Il n'y a pas besoin de cacher et montrer la logique. Simplement service va créer un composant à l'exécution en utilisant AOT ASUI MNP

2
répondu Aravind Sivam 2017-03-29 11:28:44

Essayez d'utiliser ng-window, c'est permettre au développeur d'ouvrir et de contrôler complètement plusieurs fenêtres dans des applications à une seule page de manière simple, Pas de Jquery, pas de Bootstrap.

entrez la description de l'image ici

Configration Avilable

  • fenêtre Maxmize
  • Réduire la fenêtre
  • taille Personnalisée,
  • posation personnalisée
  • la fenêtre est glisser
  • bloquer la fenêtre parent ou non
  • centrez la fenêtre ou non
  • passer les valeurs à la fenêtre chirield
  • passer les valeurs de la fenêtre chield à la fenêtre parent
  • écoute de la fermeture de la fenêtre chield dans la fenêtre parent
  • écoutez l'événement redimensionner avec votre écouteur personnalisé
  • Ouvrir avec une taille maximale ou non
  • activer et désactiver le redimensionnement de la fenêtre
  • Activer et désactiver la maximisation
  • Activer et désactiver la minimisation
0
répondu Bahgat Mashaly 2017-03-18 08:53:49