Answer the question
In order to leave comments, you need to log in
How to pass object reference as compileContext?
I found on the Internet the directive code for dynamically creating components, it uses Compiler:compileModuleAndAllComponentsAsync , ViewContainerRef:createComponent and other scary words:
import {
Compiler, NgModule, Component, Input, ComponentRef, Directive,
ModuleWithComponentFactories, OnChanges, Type,
ViewContainerRef
} from '@angular/core';
import { CommonModule } from '@angular/common';
@Directive({
selector: '[compile]'
})
export class CompileDirective implements OnChanges {
@Input() compile: string;
@Input() compileContext: any;
compRef: ComponentRef<any>;
constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {}
ngOnChanges() {
if(!this.compile) {
if(this.compRef) {
this.updateProperties();
return;
}
throw Error('You forgot to provide template');
}
this.vcRef.clear();
this.compRef = null;
const component = this.createDynamicComponent(this.compile);
const module = this.createDynamicModule(component);
this.compiler.compileModuleAndAllComponentsAsync(module)
.then((moduleWithFactories: ModuleWithComponentFactories<any>) => {
let compFactory = moduleWithFactories.componentFactories.find(x => x.componentType === component);
this.compRef = this.vcRef.createComponent(compFactory);
this.updateProperties();
})
.catch(error => {
console.log(error);
});
}
updateProperties() {
for(var prop in this.compileContext) {
this.compRef.instance[prop] = this.compileContext[prop];
}
}
private createDynamicComponent (template:string) {
@Component({
selector: 'custom-dynamic-component',
template: template,
})
class CustomDynamicComponent {}
return CustomDynamicComponent;
}
private createDynamicModule (component: Type<any>) {
@NgModule({
// You might need other modules, providers, etc...
// Note that whatever components you want to be able
// to render dynamically must be known to this module
imports: [CommonModule],
declarations: [component]
})
class DynamicModule {}
return DynamicModule;
}
}
// Шаблон компонента
<ng-container *compile="template; context: { some_key: true }"></ng-container>
// Объявление свойства template в текущем компоненте
template = `
<div *ngIf="some_key">This shit finally works, nice</div>
`;
<div>This shit finally works, nice</div>
. Answer the question
In order to leave comments, you need to log in
1. So shorter. The structural directive is sugar.
2. Because it
unfolds into this
<ng-template [compile]="template" [compileContext]="{ some_key: true }">
<ng-container></ng-container>
</ng-template>
Angular HTML compiler
Here is a component to which you can pass a dynamic template in a string and an object with data. It also works in the prod, where in the main module you need to register the module for jit once
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question