2017-01-13 4 views
2

У меня есть модальный, который динамически создается из компонента, таким образом:Как испускает событие из динамически загружаемых модального родителю

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

@Component({ 
    selector: 'comp-comp', 
    template: `MyComponent dataToPass: {{dataToPass}}, dataToPass2: {{dataToPass2}} 

      <button (click)="updateData()">Update data</button>` 
}) 
export class CompComponent { 
    @Output() setupDataUpdated = new EventEmitter();  
    private dataToPass2; 

    constructor() {} 

    ngAfterContentInit() { 
    this.dataToPass2 = this.dataToPass + ' hello'; 
    } 

    updateData() { 
    console.log('data updated'); 
    this.setupDataUpdated.emit('emitted_value'); 
    } 
} 

@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 (setupDataUpdated)="updateSetupData($event)"> 
     </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 = ''; 
    dataToPass: 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.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; 
    } 

    updateSetupData(data) { 
     console.log('update data'); 
     console.log(data); 
    } 

} 

@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'}); 
    } 
} 

(ссылающийся: Angular 2 modals shared between components).

Как вы можете видеть, я пытался выпустить событие setupDataUpdated из модального дочернего компонента, но модальный компонент-родитель, похоже, не видит это событие. Знаете ли вы, почему? Где моя ошибка?

+0

Пожалуйста, примите ответ или оставить комментарий, так что этот вопрос может быть решен. – isherwood

ответ

2

Вы должны вручную подписаться на EventEmitter, как показано ниже:

this.cmpRef.instance.setupDataUpdated.subscribe((data) => this.updateSetupData(data)); 

Modified Plunker

+0

Это похоже на правильный подход, но я думаю, что он реализован в обратном порядке. Вы добавили подписчика к модальному компоненту. Это должно быть в компоненте, который называет модальный, теперь? Кроме того, Плункер сломан. – isherwood

+0

@isherwood Фиксированный плункер – yurzui