To compile at run time, you can create a directive that will dynamically compile the template.
UPDATE:
Using compileModuleAndAllComponentsAsync for RC.6 ^
dynamic-pipe.ts
ngAfterViewInit() { const data = this.data.content; const pipe = this.data.pipe; @Component({ selector: 'dynamic-comp', template: '{{ data | ' + pipe + '}}' }) class DynamicComponent { @Input() public data: any; }; @NgModule({ imports: [BrowserModule], declarations: [DynamicComponent] }) class DynamicModule {} this.compiler.compileModuleAndAllComponentsAsync(DynamicModule) .then(({moduleFactory, componentFactories}) => { const compFactory = componentFactories.find(x => x.componentType === DynamicComponent); const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector); const cmpRef = this.vcRef.createComponent(compFactory, 0, injector, []); cmpRef.instance.data = data; }); }
RC.6 plunger example ^
OBSOLETE SOLUTION
In RC.5, you can use Compiler.compileComponentSync/Async for this:
dynamic-pipe.ts
@Directive({ selector: 'dynamic-pipe' }) export class DynamicPipe { @Input() data: CellModel; constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {} ngAfterViewInit() { const metadata = new ComponentMetadata({ template: '{{ data | ' + this.data.pipe + '}}' }); const data = this.data.content; const decoratedCmp = Component(metadata)(class DynamicComponent { data = data; }); this.compiler.compileComponentAsync(decoratedCmp) .then(factory => { const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector); this.vcRef.createComponent(factory, 0, injector, []); }); } }
And use it like this:
<template ngFor let-cell [ngForOf]="row"> <td><dynamic-pipe [data]="cell"></dynamic-pipe></td> </template>
See also the plunker RC.5 sample , which demonstrates this feature.
In any case, I think the Günter solution is preferable
yurzui
source share