typescript - Skicka kontext till en Angular 2-komponents projicerade innehåll (använda ng-content)
Jag skriver en återanvändbar Angular 2-komponent för att hämta och visa data i en tabell, med serversidig sortering, filtrering och sökning. Jag skulle vilja att varje rad i tabellen har en extra kolumn med generisk HTML med en ng-context-tagg, och jag kan göra detta.
Det vanligaste fallet för detta är att ha knappar som kan utföra åtgärder med hjälp av de data som varje rad byggdes från (till exempel navigera till en specifik sida för posten, eller ta bort posten), men det verkar inte finnas något sätt att skicka ett objekt till ContentChildren i en komponent. Jag skulle kanske kunna åstadkomma detta via direkt DOM-manipulation och inspektion, men det är både mycket hackigt och dåligt för återanvändbarhet.
Jag är inte särskilt bekymrad över något specifikt sätt att uppnå detta, så länge det:
- Tillåter mig att lägga till generisk HTML som ett barn till komponenten
- Kan skicka viss generisk data från föräldrakomponenten till dess ContentChildren (den ovan nämnda generiska HTML) på ett sätt som gör att den kan användas av händelsehanterare på barnen.
Jag använder TypeScript, så en typ-säker lösning skulle vara att föredra, men jag skulle vara glad att behöva ignorera typ-systemet om det behövs.
Min tabellkomponent (my-table) i användning skulle se ut ungefär som
<my-table /* some properties */>
<button class="row-button" type="button" (click)="navigate(/* context */)">Navigate</button>
</my-table>
med sin mall som använder ng-content på detta sätt:
// table html
<tr *ngFor="let row of rows">
<td *ngFor="let column of row.columns">{{column}}</td>
<td>
<ng-content select=".row-button"></ng-content>
</td>
</tr>
// more table html
Om jag kunde skicka en parameter till ng-content som skulle kunna användas av knappelementet skulle det räcka.
Svar #1
Om du inte är strikt med att använda ng-content, kan ng-template göra jobbet:
<my-table [rowButtonTemplate]="buttonTemplate" /* some properties */>
<ng-template #buttonTemplate let-column>
<button class="row-button" type="button" (click)="navigate(column.context)">Navigate</button>
</ng-template>
</my-table>
och sedan inuti bordet:
// table ts
@Input()
rowButtonTemplate: TemplateRef;
// table html
<tr *ngFor="let row of rows">
<td *ngFor="let column of row.columns">{{column}}</td>
<td>
<ng-container *ngTemplateOutlet="rowButtonTemplate; context: { $implicit: column, index: index }"></ng-container>
</td>
</tr>
// more table html
Svar #2
Ett sätt skulle vara en mallvariabel som låter dig explicit hänvisa till föräldern:
<my-table #myTable>
<button [context]="myTable.context">
</my-table>
Såvitt jag vet finns det planer på att göra detta mer flexibelt. Jag antar att det är detta problem https://github.com/angular/angular/issues/8563
