I'm writing angular components for the foundation css framework. I am working on the tabs component, and want to be able to pass some HTML to the <ng-content>
of this.
The problem is, I also need to pass html which a user can put bindings on, like this:
PARENT TEMPLATE
<tabs [data]='example'> <div> Age <br> {{item.age}} </div>` </tabs>
TABS COMPONENT
<ul class="tabs" #tabs> <li *ngFor="let item of data | async" (click)="tabClick($event)"> <a>{{item.name}}</a> </li> </ul> <div> <ng-content></ng-content> </div>
TABS TYPESCRIPT
@Component({ selector: 'tabs', templateUrl: './tabs.component.html' }) export class TabsComponent { @Input('data') data:any; @ViewChild('tabs') tabs: ElementRef; }
Where item
is a reference to an object in the example
array.
However, I get this error: Cannot read property 'name' of undefined
as item
is being evaluated before it is inserted into the <ng-content>
directive.
Is there a way to get around this limitation, or am I going about this the wrong way?
The first step to passing data into an Angular component is to create a custom property to bind to. This is done via “input” binding to pass data from one component to another (typically parent to child). This custom input binding is created via the @Input() decorator!
To add HTML that contains Angular-specific markup (property or value binding, components, directives, pipes, ...) it is required to add the dynamic module and compile components at runtime.
Content projection is a pattern in which you insert, or project, the content you want to use inside another component. For example, you could have a Card component that accepts content provided by another component.
update Angular 5
ngOutletContext
was renamed to ngTemplateOutletContext
See also https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29
original
ngTemplateOutlet
or ngForTemplate
can be used for that use case:
<tabs [data]='example'> <ng-template let-item> <div> Age <br> {{item.age}} </div>` </ng-template> </tabs>
@Component({ ... template: ` <ul class="tabs" #tabs> <li *ngFor="let item of data | async" (click)="tabClick($event)"> <a>{{item.name}}</a> </li> </ul> <div> <ng-template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{$implicit: (data | async)}"></ng-template> </div> ` }) class TabsComponent { @ContentChild(TemplateRef) templateRef:TemplateRef; }
See also Angular 2 bind transcluded content to loop variable
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With