Search code examples
javascriptangulartypescriptangular2-templateangular2-directives

Passing context to template through ngOutletContext in Angular2


I have a component to which I am passing a template. Inside of this component I would like to pass context so that I could display data.

@Component({
  selector: 'my-component',
  providers: [],
  template: `
    <template [ngTemplateOutlet]="templ" [ngOutletContext]="{isVisible: true}">
    </template>
  `
})
export class MyElementComponent implements OnInit {
    @ContentChild(TemplateRef) templ;
    constructor(){}
}

Now when using component inside of other component:

<my-component>
    <template>
        {{isVisible ? 'yes!' : 'no'}}
    </template>
</my-component>

So in my-component I am passing a template which is handled in it's class by @ContentChild with name templ.

Then, in my-component's template i am passing templ to ngTemplateOutlet and additionally, I am passing context using ngOutletContext which has isVisible set to true.

we should see yes! on the screen but it seems that context is never passed.

My angular version:

"@angular/common": "^2.3.1",
"@angular/compiler": "^2.3.1",
"@angular/core": "^2.3.1",

Solution

  • After a long time, I made it.

    Example with single value:

    @Component({
      selector: 'my-component',
      providers: [],
      template: `
        <template [ngTemplateOutlet]="templ" [ngOutletContext]="{isVisible: true}">
        </template>
      `
    })
    export class MyElementComponent implements OnInit {
        @ContentChild(TemplateRef) templ;
        constructor(){}
    }
    
    <my-component>
        <template let-isVisible="isVisible">
            {{isVisible ? 'yes!' : 'no'}}
        </template>
    </my-component>
    

    Example with loop:

    @Component({
      selector: 'my-component',
      providers: [],
      template: `
        <div *ngFor="let element of data">
            <template [ngTemplateOutlet]="templ" [ngOutletContext]="{element: element}">
            </template>
        </div>
      `
    })
    export class MyElementComponent implements OnInit {
        @ContentChild(TemplateRef) templ;
        constructor(){
            this.data = [{name:'John'}, {name:'Jacob'}];
        }
    }
    
    --- 
    
    <my-component>
        <template let-element="element">
            {{element.name}}
        </template>
    </my-component>
    

    Result:

    <div>John</div>
    <div>Jacob</div>