cgatian
cgatian

Reputation: 22994

Pass different context to ngIf

Take the following template example. The Im creating a template context of user with the as syntax and would like to pass that context into the userTmpl. From what I can tell there's no way to pass context outside of what is used by the ngIf condition. Which in this example, is the showUser property.

<ng-container *ngIf="user$ | async as user">
    <ng-container *ngIf="showUser; then userTmpl; else emptyTmpl"></ngcontainer>
</ng-container>

How can you pass the user template input variable to the nested templateRef?

Looking at the source, the ngIf directive looks like it sets the context to the condition of the ngIf. Im not aware of a way to basically override that context variable thats used within the templates

Something like this would be ideal, but not seeing a way to do it.

<ng-container *ngIf="showUser; then userTmpl; else emptyTmpl; context: user"></ngcontainer>

Upvotes: 47

Views: 33142

Answers (4)

coreuter
coreuter

Reputation: 3572

There are two very similar ways to solve this. I've created a stackblitz with the two solutions (tested with Angular 6.0.1 and the latest 6.1.8) for passing data to different templates based on a condition.

version #1

    <ng-container *ngTemplateOutlet="showUser ? userTmpl : emptyTmpl; context: { $implicit: user }">
    </ng-container>

    <ng-template #userTmpl let-user>
        ...
    </ng-template>

    <ng-template #emptyTmpl let-user>
        ...
    </ng-template>

version #2

Another possibility is to use @Ben's solution, but then you have to omit the let-user part (and fix the closing tag in his code). This way the code would look like this.

    <ng-container *ngTemplateOutlet="showUser ? userTmpl : emptyTmpl; context: user">
    </ng-container>

    <ng-template #userTmpl>
        ...
    </ng-template>

    <ng-template #emptyTmpl>
        ...
    </ng-template>

Upvotes: 48

Ben
Ben

Reputation: 4110

You can achieve that this way :

<ng-container *ngTemplateOutlet="showUser ? userTmpl : emptyTmpl; context: user"></ngcontainer>

Upvotes: 3

Shlomi Levi
Shlomi Levi

Reputation: 3305

Yes you can!

Your $implicit is the x and x is user from ngif (in your case)

Because this._context.$implicit = this._context.ngIf = condition

Check this example:

@Component({
  selector: 'app-root',
  template: `
    <h1>{{title}}</h1>
    <div *ngIf="user;then content else other_content">here is ignored</div>

    <ng-template #content let-x="$implicit">{{x|json}}content here...</ng-template>
    <ng-template #other_content>other content here...</ng-template>
  `,
  styles: []
})
export class AppComponent {
  title = 'app';
  user = { name: 'wizardnet972' };
}

Upvotes: 4

Edmundo Santos
Edmundo Santos

Reputation: 8287

Take a look at NgTemplateOutlet.

Something like that would work:

<ng-container *ngIf="user$ | async as user">
    <ng-container *ngIf="showUser">
      <ng-container *ngTemplateOutlet="userTmpl; context: { $implicit: user }"></ng-container>
    </ng-container>
</ng-container>

<ng-template #userTmpl let-user>
  {{ user | json }
</ng-template>

Upvotes: 7

Related Questions