ng2-bootstrap, вызовите Modal, определенный в дочернем компоненте из родительского компонента

Я использую ng2-bootstrap для модального материала.

Я пытаюсь разделить свои модальные окна и другие компоненты. Итак, у меня есть следующие файлы:

addPlaylist.modal.ts

import {Component} from '@angular/core';
import {CORE_DIRECTIVES} from '@angular/common';


import {MODAL_DIRECTVES, BS_VIEW_PROVIDERS} from 'ng2-bootstrap/ng2-bootstrap';

@Component({
  selector: 'addplaylist-modal',
  directives: [MODAL_DIRECTVES, CORE_DIRECTIVES],
  viewProviders: [BS_VIEW_PROVIDERS],
  templateUrl: 'app/channel/modals/addPlaylistModal.html'
})

export class AddPlaylistModalComponent {
  constructor() {
    console.log(this);
  }
}

addPlaylistModal.html

<div bsModal #lgModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" (click)="lgModal.hide()" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title">Large modal</h4>
      </div>
      <div class="modal-body">
        ...
      </div>
    </div>
  </div>
</div>

В html родительского компонента у меня есть такой фрагмент кода:

  <a (click)="lgModal.show()"><span class="bigplus pull-right"></span></a>
   //some other code
  <addplaylist-modal></addplaylist-modal>

Это родительский компонент: channel.component.ts

import { AddPlaylistModalComponent } from './shared/addPlaylist.modal';

@Component({
  selector: 'channel',
  styleUrls: ['app/channel/channel.css'],
  directives: [PlatformsComponent, PagesComponent, PlaylistComponent, VideosComponent, AddPlaylistModalComponent],
  providers: [PlatformService],
  templateUrl: 'app/channel/channel.html'
})

Я хочу, чтобы родительский компонент мог получить к нему доступ и открыть модальное окно, даже если я напишу (click) = lgModal.show () в родительском компоненте.

Теперь, если я нажму на <a (click)="lgModal.show()"><span class="bigplus pull-right"></span></a>, он скажет «не могу прочитать отображение свойств undefined.

Итак, как сообщить родительскому компоненту, что lgModal определен и находится в его дочернем компоненте.


person Xinrui Ma    schedule 17.06.2016    source источник


Ответы (1)


Ваше решение может выглядеть примерно так:

ChildComponent

@Component({
  ...
  exportAs: 'child'  <== add this line
})
export class AddPlaylistModalComponent {
  @ViewChild('lgModal') lgModal; <== reference to Modal directive
  show(){   <== public method
    this.lgModal.show(); 
  }
}

ParentComponent

template: `<a class="btn btn-success" (click)="c.show()">Add</a>
           <addplaylist-modal #c="child"></addplaylist-modal>`

См. Также заполненный образец здесь https://plnkr.co/edit/2UAB7lpqqAvchTsLwzr6?p=preview

person yurzui    schedule 17.06.2016
comment
Я получаю platform-browser.umd.js:2306 EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property 'parentInjector' of undefined - person Pritesh Acharya; 18.07.2016
comment
Как работает строка this.viewContainerRef = viewContainerRef; в приведенном вами примере. У класса App нет свойства или члена с именем viewContainerRef. - person Pritesh Acharya; 19.07.2016
comment
@Pritesh Acharya Это то же самое, что private viewContainer в конструкторе plnkr.co/edit/jjmPvd8Xpue8Pview / а>. Посмотрите эту документацию valor-software.com/ng2-bootstrap/#/modals (Не забудьте добавить хак в корневой компонент вашего приложения) - person yurzui; 19.07.2016
comment
AFAIK в предыдущем примере this.viewContainerRef = viewContainerRef; должен вызывать ошибку компиляции, потому что у него нет модификатора public, private или protected в конструкторе. - person Pritesh Acharya; 19.07.2016
comment
@yurzui Plunker не работает, но я, глядя на код в plunker, смог заставить свою работать! За проголосовали конечно. - person Locohost; 21.02.2017