typescript - Angular ng-content: hur hittar man element inuti?


Jag har en komponent som deklarerar lite extern HTML runt en <ng-content>-tagg. Men om innehållet är av en viss komponentklass, eller om det innehåller vissa taggar, vill jag kunna få åtkomst till dem.

Till exempel, i koden nedan har komponenten MyComponent satts som innehållet i MyWrapper. Från inom MyWrapper, hur kan jag få tag på MyComponent som har fastnat i den?

Exempel

--Omslagmall--

...
<ng-content #content></ng-content>
...

--Användning av Wrapper--

<my-wrapper>
  <my-component></my-component>
</my-wrapper>

Min preferens skulle vara att kunna få ett objekt som representerar komponenten som sattes in i ng-content, så att jag kan komma åt det med TypeScript. Men jag nöjer mig med att bara kunna få DOM-objekt. Eller, om jag helt är på fel spår och borde göra detta på ett annat sätt, välkomnar jag det också.

Svar #1

Efter att ha läst lite verkar det som att en liten justering av koden är nödvändig i wrapper-klassen för att kunna komma åt DOM-elementen:

Istället för

...
<ng-content #content></ng-content>
...

Som detta svar på en annan fråga indikerar, måste man omsluta ng-content i ett div-element. Därefter använder man @ViewChild för att få åtkomst till det, som följer:

--Mall--

<div #content>
  <ng-content></ng-content>
</div>

--Klass--

@ViewChild('content')
private content;

Innehållsfältet kommer att vara tillgängligt från och med AfterViewInit-metoden i wrapper-komponenten (men inte nödvändigtvis innan):

ngAfterViewInit() {
  if (this.content) {
    console.log('content was present');
  }
  if (this.content instanceof MyComponent) {
    console.log('this should work too, but it doesn't.');
  }
}

En nackdel med detta är att jag inte har upptäckt ett sätt att återgå till den ursprungliga komponentklassen.

Svar #2

Jag gjorde det här för ett tag sedan och har ingen kodbit att visa det med, så jag hoppas att jag minns det rätt

i din mall måste du göra följande:

<my-wrapper>
  <my-component #mySubComponent></my-component>  
</my-wrapper>

och i din MyWrapperComponent följande:

@ContentChild('mySubComponent')
private subComponent: MyComponent;

ngAfterContentInit() {
    // You have access here to your public properties and methods of your sub component
}