Как получить доступ к дочернему компоненту внутри ngb-tab (для целей проверки)

Предположим, что у вас есть этот шаблон (для родительского компонента)

<button ... (click)="Save()">
...
<ngb-tabset [activeId]="selectedTab" #tabs>
  <ngb-tab id="tab1">
    <template ngbTabTitle>tab1</template>
    <template ngbTabContent>
      <child-comp1 #comp1>
      </child-comp1>
    </template>
  </ngb-tab>
  <ngb-tab id="tab2">
    <template ngbTabTitle>tab2</template>
    <template ngbTabContent>
      <child-comp2 #comp2>
      </child-comp2>
    </template>
  </ngb-tab>
  ...
</ngb-tabset>

И внутри каждого дочернего компонента (child-comp1...) у меня есть форма и входные данные с некоторыми проверками.

Как я могу получить доступ к методу дочернего компонента из родительского компонента по запросу, я имею в виду что-то вроде этого:

Save(){
  if(Validate()){
    //Save an object ...
  }
}

Validate(){
  if(!this.comp1.Validate()){
    // Activate tab1
    return false;
  }
  else if(!this.comp2.Validate()){
    // Activate tab2
    return false;
  }
  //...
  return true;      
}

В родительском компоненте у меня есть:

// imports ...
@Component({ ... })
export class parent implements OnInit {
  @ViewChild(ChildComp) comp1: ChildComp;
  @ViewChild('comp2') comp2;
  @ViewChild('tabs') tabs;
  ...
  Validate(){...}
  Save(){...}
}

comp1 и comp2 всегда undefined в методе проверки!

tabs вернуть объект, но я не смог найти способ добраться до дочернего компонента!


person A.Akram    schedule 06.09.2016    source источник
comment
Вы проверили конструктор или ngAfterViewInit()? @ViewChild() еще не назначено в конструкторе. Также был бы полезен еще один код. Где находится @ViewChild(....) и связанный с ним код. Где HTML показан в вашем вопросе?   -  person Günter Zöchbauer    schedule 06.09.2016
comment
В методе Validate() после нажатия кнопки.   -  person A.Akram    schedule 06.09.2016
comment
@GünterZöchbauer, я немного обновил вопрос. Надеюсь теперь стало понятнее!   -  person A.Akram    schedule 06.09.2016


Ответы (3)


У меня была та же проблема, простым решением было бы установить destroyOnHide input значение false, что предотвращает уничтожение вкладок, когда они скрываются.

<ngb-tabset [destroyOnHide]="false">
  ...
</ngb-tabset>
person Mehrshad Zandigohar    schedule 14.09.2017

В моем случае проблема была связана с двумя вещами:

  1. Пришлось использовать ngAfterViewInit вместо ngOninit
  2. ngb-tabset был обернут оператором *ngIf. Изменено на [hidden]

P.S для тех, кто столкнулся с этой проблемой при попытке создать динамический компонент, вот код и для этой части:

HTML

  <ngb-tabset type="pills" [orientation]="currentOrientation">
    <div #dynamicComponent></div>
  </ngb-tabset>

ТС

 @ViewChild('dynamicComponent', { read: ViewContainerRef })
  public viewContainerRef: ViewContainerRef

 constructor(   
    private _componentFactoryResolver: ComponentFactoryResolver) {
  }

  public ngAfterViewInit(): void {
    const component = this._componentFactoryResolver.resolveComponentFactory(TabComponent)
    const ref = this.viewContainerRef.createComponent(component)
    ref.instance.someValue = 'something'
    ref.changeDetectorRef.detectChanges()
  }
person Arsen Khachaturyan    schedule 24.07.2018

Это потому, что они находятся внутри тега <template>. Эти элементы не создаются так, как они показаны в шаблоне. То, как они на самом деле создаются в DOM, зависит от того, что <ngb-tab> делает с шаблоном, которому он передается.

Я думаю, что вместо этого необходимо использовать ElementRef.nativeElement.querySelector(...) или подобное.

person Günter Zöchbauer    schedule 06.09.2016