9

I need to pass an expression to a component that will be evaluated inside an component's template.

For example, component:

@Component({
  selector: 'app-my-component',
  ...
})
export class MyComponent {
  @Input items: MyClass;
  @Input expression: String;
  ...
}

with component's template:

<div *ngFor="let item of items">
  {{expression}}
</div>

Usage of MyComponent:

<app-my-component [items]="listOfItems" [expression]="'[item.id] item.name'">
</app-my-component>

As there will be more than one input, I would like to avoid usage of TemplateRef.

10
  • 1
    What is '[item.id] item.name' supposed to do? That doesn't look like an expression to me. You can't pass bindings around. Commented Oct 11, 2016 at 9:24
  • pass it as [expression]=" '{"id":[item.id],"name": item.name}' " and use as expression.id and expression.name Commented Oct 11, 2016 at 9:49
  • @GünterZöchbauer this should evaluate to string, for item = {"id": 1, "name" : "Item1"} to [1] Item1 Commented Oct 11, 2016 at 10:44
  • @AtalKishore I need input 'expression' to be generic, so in MyComponent's view I can just pass it as an expression to be evaluated or as a template, without knowing it's structure Commented Oct 11, 2016 at 10:45
  • then use [expression]=" '[' + item.id + '] ' + item.name " Commented Oct 11, 2016 at 10:48

1 Answer 1

20

Maybe one of this options can helps you:

1) Using ngForTemplate input property of NgFor directive:

Component

@Component({
  selector: 'app-my-component',
  template: `
  <div *ngFor="let item of items template: itemTemplate"></div>`
})
export class MyComponent {
  @Input() items: any;
  @ContentChild(TemplateRef) itemTemplate: TemplateRef<any>;
}

Parent

<app-my-component [items]="listOfItems">
  <ng-template let-item>[{{item.id}}] {{item.name}}</ng-template>
</app-my-component>

Plunker

2) Using the NgTemplateOutlet directive

Component

@Component({
  selector: 'app-my-component',
  template: `
  <div *ngFor="let item of items">
    <ng-template [ngTemplateOutlet]="itemTemplate" [ngTemplateOutletContext]="{ $implicit: item }"></ng-template>
  </div>`
})
export class MyComponent {
  @Input() items: any;
  @ContentChild(TemplateRef) itemTemplate: TemplateRef<any>;
}

Parent remains the same:

<app-my-component [items]="listOfItems">
  <ng-template let-item>[{{item.id}}] {{item.name}}</ng-template>
</app-my-component>

Plunker

This way inside of <ng-template let-item>...</ng-template> you can use desired expression

Sign up to request clarification or add additional context in comments.

1 Comment

The first one doesn't seem to work anymore. Other than the change to ng-template I can't figure out why its is not working for me. It gives me no items, but does error when I use the wrong let-* property...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.