Вариант 1
Использовать кастомный pipe
Живой пример:
import { UpperCasePipe, LowerCasePipe } from '@angular/common'
const PIPES_COLLECTION = {
'uppercase': new UpperCasePipe(),
'lowercase': new LowerCasePipe()
};
@Pipe({
name: 'dynamicPipe'
})
export class DynamicPipe implements PipeTransform {
transform(val, pipeName: string) {
return PIPES_COLLECTION[pipeName].transform(val);
}
}
Минус в том, что нужно вручную перечислять доступные наборы пайпов
___________________________________________________________________________________________________________________
Вариант 2
Использовать директиву, которая динамически генерирует результат через Compiler
Живой пример
Минусы - генерируется лишняя разметка, нужно больше времени на компиляцию и
не будет работать с AOT@Directive({
selector: '[dynamicPipe]'
})
export class DynamicPipeDirective {
@Input() dynamicPipe: DynamicPipeModel;
cmpRef: ComponentRef<any>;
constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {}
ngAfterViewInit() {
const data = this.dynamicPipe.name;
const pipe = this.dynamicPipe.pipe;
@Component({
selector: 'dynamic-comp',
template: '{{ data | ' + pipe + '}}'
})
class DynamicComponent {};
@NgModule({
imports: [CommonModule],
declarations: [DynamicComponent]
})
class DynamicModule {}
this.compiler.compileModuleAndAllComponentsAsync(DynamicModule)
.then((moduleWithComponentsFactory) => {
const compFactory = moduleWithComponentsFactory.componentFactories.find(x => x.componentType === DynamicComponent);
const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
this.cmpRef = this.vcRef.createComponent(compFactory, 0, injector, []);
this.cmpRef.instance.data = data;
});
}
ngOnDestroy() {
if(this.cmpRef) {
this.cmpRef.destroy();
}
}
}