2016-12-22 8 views
0

benutzen ich dieses Beispiel: How to dynamically create bootstrap modals as Angular2 components?
meinen eigenen zupft mit dynamischer Erzeugung von verschiedenen oder gleichen modals zwischen mehr Komponenten gemeinsam zu entwickeln.
Leider habe ich einige Schwierigkeiten, weil ich nicht weiß, wie man Daten von der Elternkomponente an die Modale weitergibt. In meinem Plunk (https://plnkr.co/edit/RgI1e9PobC7FloLHpEFD?p=preview) werden die zu übergebenden Daten "dataToPass" genannt. Irgendwelche Ideen?Angular 2 Weitergabe von Daten aus Stammkomponente zu dynamischen modal

Hier unten meine app.ts:

//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: 'comp-comp', 
    template: `MyComponent` 
}) 
export class CompComponent { } 

@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: '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; 

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

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

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

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

    private dataToPass: string; 
    constructor(private sharedService:SharedService) { 
    this.dataToPass = 'data to pass'; 
    } 

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

} 

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

Vielen Dank im Voraus.

+0

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child –

Antwort

0

Wenn jemand könnte interessieren, konnte ich die Lösung finden.

gebe ich den Daten-I als Parameter der next Funktion benötigen, als Subjekt verwendet werden, können Werte für seine Abonnenten zu emittieren:

showDialog() { 
    this.sharedService.showModal.next({'type': CompComponent, 'title': 'titolo1', 'dataToPass': 'dataToPass'}); 
    } 

Dann habe ich, die Daten zu CompComponent innen subscribe Funktion übergeben (nach diesem Beispiel: Angular 2 Passing data to component when dynamically adding the component), auf diese Weise:

let factory = this.componentFactoryResolver.resolveComponentFactory(data.type); 
    this.cmpRef = this.theBody.createComponent(factory); 
    this.cmpRef.instance.dataToPass = data.dataToPass; 

Hier unten ist der gesamte Code, können Sie es here auf Plunker auch sehen.

//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: 'comp-comp', 
    template: `MyComponent {{dataToPass}}` 
}) 
export class CompComponent { } 

@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({'type': CompComponent, 'title': 'titolo2', 'dataToPass': 'dataToPass'}); 
    } 

} 

@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">{{theHeader}}</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; 

    theHeader: string = ''; 
    cmpRefBody:ComponentRef<any>; 

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

    sharedService.showModal.subscribe(data => { 
     if(this.cmpRef) { 
     this.cmpRef.destroy(); 
     } 
     let factory = this.componentFactoryResolver.resolveComponentFactory(data.type); 
     this.cmpRef = this.theBody.createComponent(factory); 
     this.cmpRef.instance.dataToPass = data.dataToPass; 
     this.theHeader = data.title; 
     console.log(data.title); 
     console.log(data.dataToPass); 
     $('#theModal').modal('show'); 
    }); 
    } 

    close() { 
    if(this.cmpRef) { 
     this.cmpRef.destroy(); 
    } 
    this.cmpRef = 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({'type': CompComponent, 'title': 'titolo1', 'dataToPass': 'dataToPass'}); 
    } 

} 

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