angular - Prístup k vnoreným obsahovým deťom


@Directive({
  selector: '[some-directive]'
})
export class SomeDirective...
@Component({
  selector: 'inner-component',
  template: `
    <div some-directive></div>
  `
})
export class InnerComponent {
}
@Component({
  template: `
    <inner-component></inner-component>
  `
})
export class OuterComponent {
  @ContentChildren(SomeDirective, {descendants: true}) elementsWithDirective: QueryList<SomeDirective>;
}

Je toto správny spôsob, ako získať tieto direktívy? elementsWithDirective vracia prázdne pole výsledkov. Nemôžem k nim pristupovať týmto spôsobom. Jediný spôsob, ako sa problém zbaviť, je umiestniť <div app-some-directive></div> priamo do pohľadu OuterComponent, ale chcem sa tomu vyhnúť.

Odpoveď č. 1

Podľa mojich informácií momentálne neexistuje spôsob, ako priamo získať vnukovské prvky z komponentu. Neviem, aký je váš prípad použitia, ale mohli by ste:

  1. Pridajte @ViewChild(InnerComponent) innerComponent: InnerComponent do vášho vonkajšieho komponentu
  2. Pridajte @ViewChild(SomeDirective) someDirective: SomeDirective do svojej vnútornéj komponenty
  3. z vonkajšej komponenty pristupujte k svojej direktíve cez vnútornú komponentu v ngAfterViewInit ngAfterViewInit(): void { console.log(this.innerComponent.someDirective); }

stackblitz tu

Odpoveď č. 2

Zdá sa, že ste zmätený ohľadom contentChildren a viewChildren. Vo vašom prípade by ste mali použiť viewChildren na dotazovanie SomeDirective v InnerComponent a emitovať výsledky do OuterComponent, napríklad.

@Component({
  selector: 'outer-component',
  template: `    <inner-component 
    (elementsWithDirectiveChanges)="elementsWithDirectiveChanged($event)"> 
    </inner- 
    component>`
})
export class OuterComponent {
  elementsWithDirectiveChanged(change: any) {
    console.log(change);
  }
}

@Component({
  selector: 'inner-component',
  template: `
    <div some-directive>inner</div>
  `
})
export class InnerComponent {
  @ViewChildren(SomeDirective) elementsWithDirective!: QueryList<SomeDirective>;
  @Output() elementsWithDirectiveChanges = new EventEmitter();

  ngAfterViewInit() {
    this.elementsWithDirectiveChanges.emit(this.elementsWithDirective);
  }
}

demo https://stackblitz.com/edit/angular-2oesig?file=src%2Fapp%2Fhello.component.ts