Как передать событие из динамически загруженного модального окна в родительский

У меня есть модальное окно, которое динамически создается из компонента следующим образом:

@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, совместно используемые компонентами) .

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


person B. Ciervo    schedule 13.01.2017    source источник
comment
Пожалуйста, примите ответ или оставьте комментарий, чтобы решить этот вопрос.   -  person isherwood    schedule 13.07.2017


Ответы (1)


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

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

Измененный планкер

person yurzui    schedule 13.01.2017
comment
Это кажется правильным подходом, но я думаю, что он реализован наоборот. Вы добавили подписчика в модальный компонент. Теперь он должен быть в компоненте, который вызывает модальное окно? Кроме того, Плункер сломан. - person isherwood; 13.07.2017
comment
@isherwood Фиксированный плункер - person yurzui; 13.07.2017