1

J'ai une application Angular 2 typique avec de nombreux composants.
J'ai installé ce composant modal: https://github.com/pleerock/ng2-modal.
Existe-t-il un moyen de partager les mêmes modaux entre plusieurs composants? J'explique mieux. Je voudrais que le même modal devrait s'ouvrir sur le clic des différents boutons à l'intérieur de différents composants. C'est possible?Angular 2 modaux partagés entre les composants

J'ai essayé ce type d'approche https://plnkr.co/edit/RgI1e9PobC7FloLHpEFD?p=preview mais ce n'est pas la bonne façon, car elle ajoute toujours du contenu au modal.

je poste ici en dessous de mon fichier app.ts:

21/12/2016 mise à jour
Après suggestion @echonax, je mis à jour mon Plunk:

//our root app component 
import { 
    NgModule, 
    ComponentRef, 
    Injectable, 
    Component, 
    Injector, 
    ViewContainerRef, 
    ViewChild, ComponentFactoryResolver} from "@angular/core"; 
import {BrowserModule} from '@angular/platform-browser' 
import {Subject} from 'rxjs/Subject'; 

@Injectable() 
export class SharedService { 
    showModal:Subject<any> = new Subject(); 
} 


@Component({ 
    selector: 'child-component', 
    template: ` 
     <button (click)="showDialog()">show modal from child</button> 
    `, 
}) 
export class ChildComponent { 
    constructor(private sharedService:SharedService) {} 

    showDialog() { 
    this.sharedService.showModal.next(CompComponent); 
    } 

} 


@Component({ 
    selector: 'comp-comp', 
    template: `MyComponent` 
}) 
export class CompComponent { } 


@Component({ 
    selector: 'modal-comp', 
    template: ` 
    <div class="modal fade" id="theModal" tabindex="-1" role="dialog" aria-labelledby="theModalLabel"> 
    <div class="modal-dialog largeWidth" role="document"> 
     <div class="modal-content"> 
     <div class="modal-header"> 
     <h4 class="modal-title" id="theModalLabel">The Label</h4></div> 
     <div class="modal-body" #theBody> 
     </div> 
    <div class="modal-footer"> 
    <button type="button" class="btn btn-default" data-dismiss="modal" (close)="close()">Close</button> 
    </div></div></div></div> 
` 
}) 
export class ModalComponent { 
    @ViewChild('theBody', {read: ViewContainerRef}) theBody; 

    cmp:ComponentRef<any>; 
    cmpRef:ComponentRef<any>; 

    constructor(
    sharedService:SharedService, 
    private componentFactoryResolver: ComponentFactoryResolver, 
    injector: Injector) { 

    sharedService.showModal.subscribe(type => { 
     if(this.cmp) { 
     this.cmp.destroy(); 
     } 
     let factory = this.componentFactoryResolver.resolveComponentFactory(type); 
     this.cmpRef = this.theBody.createComponent(factory) 
     $('#theModal').modal('show'); 
    }); 
    } 

    close() { 
    if(this.cmp) { 
     this.cmp.destroy(); 
    } 
    this.cmp = null; 
    } 
} 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Hello</h2> 
     <button (click)="showDialog()">show modal</button> 
     <child-component></child-component> 
    </div> 
    `, 
}) 
export class App { 
    constructor(private sharedService:SharedService) {} 

    showDialog() { 
    this.sharedService.showModal.next(CompComponent); 
    } 

} 

@NgModule({ 
    imports: [ BrowserModule ], 
    declarations: [ App, ModalComponent, CompComponent, ChildComponent], 
    providers: [SharedService], 
    entryComponents: [CompComponent], 
    bootstrap: [ App, ModalComponent ] 
}) 
export class AppModule{} 

Restez à l'écoute!

+0

Qu'avez-vous essayé? Essayez de référencer et d'afficher le code qui ne fonctionne pas pour essayer d'obtenir de l'aide. Les gens vont répondre avec plus d'aide quand vous avez essayé quelque chose et juste besoin d'une solution, plutôt que de demander à quelqu'un de le faire pour vous. –

+0

Ok, je l'ai fait. Quoi qu'il en soit, toutes les approches que j'ai essayées correspondaient à ce dont j'avais besoin, donc je ne pensais pas qu'il était utile de les poster. J'ai essayé le tout hier après-midi, ce n'était pas de la paresse. –

+1

Cette version originale de plunker est ma question en fait: http://stackoverflow.com/questions/36566698/how-to-dynamically-create-bootstrap-modals-as-angular2-components et @ Günter a fait une réponse étonnante que je pense est vraiment sous-estimé. Il y a une petite erreur, j'en parlerai à Günter mais vous pouvez trouver la version corrigée ici: https://plnkr.co/edit/oMCZIJq58WdLgYf2D0Di?p=preview – echonax

Répondre

2

Cette version originale de plunker est ma question en fait: How to dynamically create bootstrap modals as Angular2 components?

@ Günter a fait une réponse étonnante que je pense est vraiment sous-estimés.

Le plunker a une petite erreur, vous pouvez trouver la version fixe ici: https://plnkr.co/edit/oMCZIJq58WdLgYf2D0Di?p=preview

if cas font référence au mauvais champ, donc changer

if(this.cmp) { 
    this.cmp.destroy(); 
} 

avec

if(this.cmpRef) { 
    this.cmpRef.destroy(); 
} 
1

Je sais que ce sujet a 6 mois, mais c'était vraiment une bonne affaire pour moi. J'ai donc fait un module npm pour permettre le partage modal entre les composants avec des données partagées et l'ouverture/la fermeture/les événements à distance.

N'hésitez pas à le vérifier: https://github.com/biig-io/ngx-smart-modal.

La démo est ici: https://biig-io.github.io/ngx-smart-modal/

Compatible avec angulaire> = 2.0.0

+1

Merci beaucoup! Je vais essayer de l'utiliser pour mes scripts suivants. –

+0

Avec plaisir! N'hésitez pas à créer quelques problèmes pour m'aider à l'améliorer;) –

+0

MISE À JOUR: J'ai mis à jour le composant pour résoudre les problèmes de construction AOT. J'ai aussi édité le lien du repo parce qu'il bouge;) –