Reputation: 19754
I've manually created an instance of a class. This class has a @Component
decorator. How do I render its template?
@Component({ template: `hello {{ who }}` })
class Greeting {
constructor (public who: string) { }
}
@Component({ template: `<ng-somehow-render [instance]="greeting"/>` })
class OtherComponent {
public greeting: Greeting
constructor () {
this.greeting = new Greeting('world')
}
}
ComponentFactoryResolver
will give me an instance of the component. I already have the instance and I want to render it.ngComponentOutlet
will internally create the instance. My instance is then useless.Upvotes: 2
Views: 1559
Reputation: 13539
Looks like you need a middleware component to render instances of another components.
it could be this one
@Component({
selector: 'ng-somehow-render',
template: '',
})
export class NgSomehowRenderComponent implements OnInit {
@Input() instance: any;
constructor (
private cfr: ComponentFactoryResolver,
private vcr: ViewContainerRef,
private cdr: ChangeDetectorRef,
) {
}
public ngOnInit(): void {
const componentFactory = this.cfr.resolveComponentFactory(this.instance.constructor);
this.vcr.clear();
const componentRef = this.vcr.createComponent(componentFactory);
for (const key of Object.getOwnPropertyNames(this.instance)) {
componentRef.instance[key] = this.instance[key];
}
this.cdr.detectChanges();
}
}
Simply add its declaration into your modules.
BTW the Greeting
component should be declared in your modules in entryComponents
.
@NgModule({
declarations: [AppComponent, Greeting, NgSomehowRenderComponent],
imports: [BrowserModule],
providers: [],
bootstrap: [AppComponent],
entryComponents: [Greeting]
})
Because Angular will try to solve constructor dependencies you need to add @Optional()
decorator there.
@Component({
template: `hello {{ who }}`
})
export class Greeting {
constructor(@Optional() public who: string) {}
}
profit.
You can check live demo here: https://codesandbox.io/s/jolly-villani-32m5w?file=/src/app/app.component.ts
All the things from the official doc, so you can use it without problems: https://angular.io/guide/dynamic-component-loader#resolving-components
Upvotes: 1