1

I have a Component with view like below:

<div class="dropdown user-select">
    <div class="gray-input dropdown-toggle" type="button" id="assigned_to" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
        <ng-content select="[selected-item-tmpl]"></ng-content>
        <span class="caret"></span>
    </div>

    <ul class="dropdown-menu" aria-labelledby="assigned_to">
        <li *ngFor="let item of items" 
            (click)="itemClick$.next(item)">
            <ng-content select="[list-item-tmpl]"></ng-content>
        </li>
    </ul>
</div>

According to this and this, I now know that Transclusion with ngFor will not work.

But according to this, if I change my component to following:

<div class="dropdown user-select">
    <div class="gray-input dropdown-toggle" type="button" id="assigned_to" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
        <ng-content select="[selected-item-tmpl]"></ng-content>
        <span class="caret"></span>
    </div>

    <ul class="dropdown-menu" aria-labelledby="assigned_to">
        <li *ngFor="let item of items" 
            (click)="itemClick$.next(item)">
            <template [ngTemplateOutlet]="template" 
                      [ngOutletContext]="{item: item}">
            </template>
        </li>
    </ul>
</div>

For brevity the Component.ts after change:

@ContentChild(TemplateRef) template: TemplateRef<any>;

and use like following:

<ds-combobox [items]="attendeeService.users"
             (itemClicked)="applySelectedUser($event)">
    <div selected-item-tmpl>
     --> <img *ngIf="newTask.assignedTo.photo" [src]="newTask.assignedTo.photo">{{newTask.assignedTo.name}}
        <div *ngIf="!newTask.assignedTo.photo && newTask.assignedTo.initials" class="pull-left photo-avatar">
            <div>{{newTask.assignedTo.initials}}</div>
        </div>
    </div>
    <div list-item-tmpl>
        <template let-item="item"><b>{{item.name}}</b></template>
    </div>
</ds-combobox>

Then I do not get any errors and it seems to run but the template for the ngTemplateOutlet seems to take the template from the first slot and ends up being <img src="null">. If I remove the first slot and just leave <template let-item="item"><b>{{item.name}}</b></template> then it seems to work fine. So basically, how do I combine using Transclusion with Template Outlet in the same component?

NOTE: After thinking for a while, I just reversed the <template> position with <ng-content> and it seems to work now as expected. But the question still remains why though?

Community
  • 1
  • 1
lbrahim
  • 3,710
  • 12
  • 57
  • 95
  • Please add more code. How do you define `template` variable in your component? – yurzui Oct 21 '16 at 14:51
  • @yurzui Updated code. – lbrahim Oct 21 '16 at 14:57
  • If you use `@ViewChildren(TemplateRef) templates: QueryList; and then `ngAfterViewInit() { console.log(this.templates.toArray().length); }`. What do you get printed? – Günter Zöchbauer Oct 21 '16 at 14:59
  • 1
    Please improve this plunker https://plnkr.co/edit/GExkPsqeVoqZn8bjsvgk?p=preview to get your error – yurzui Oct 21 '16 at 14:59
  • You can also use `ngForTemplate` instead of `ngTemplateOutlet`. More details here http://stackoverflow.com/questions/39974126/how-to-pass-an-expression-to-a-component-as-an-input-in-angular2/39977298#39977298 – yurzui Oct 21 '16 at 15:02
  • @yurzui I have updated the plunkr here: https://plnkr.co/edit/t6zX1zjlzmHEpqj4R3PW – lbrahim Oct 24 '16 at 09:56
  • @GünterZöchbauer It shows `3`. I have tried to imitate as close as possible here: https://plnkr.co/edit/t6zX1zjlzmHEpqj4R3PW – lbrahim Oct 24 '16 at 09:56
  • 1
    https://plnkr.co/edit/FFNSXcuvec0W9xwKWKFq?p=preview – yurzui Oct 24 '16 at 10:05

0 Answers0