Here is a rough example of this kind of implementation.
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[buttonView]'
})
export class ButtonViewDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
import { ComponentFactoryResolver } from '@angular/core';
import { OneComponent, TwoComponent } from './components';
@Component({
selector: 'right-panel',
encapsulation: ViewEncapsulation.Emulated,
template: `
<div>
<ul>
<li *ngFor="let button of buttons">
<button (click)="onButtonClick(button)">{{button.name}}</button>
</li>
</ul>
</div>
<div>
<ng-template buttonView></ng-template>
</div>
`
})
class RightPanelComponent {
public buttons: any = [
{
name: 'Button 1',
component: OneComponent
},
{
name: 'Button 2',
component: TwoComponent
}
]
@ViewChild(ButtonViewDirective)
public buttonViewContent: ButtonViewDirective;
constructor(
protected _cmpFactoryResolver: ComponentFactoryResolver,
) {}
public onButtonClick(button: any): void {
this._createComponent(button);
}
private _createComponent(button: any): void {
if (button === null) {
return;
}
setTimeout(() => {
const cmpFactory = this._cmpFactoryResolver.resolveComponentFactory(button.component);
const viewContainerRef = this.buttonViewContent.viewContainerRef;
viewContainerRef.clear();
viewContainerRef.createComponent(cmpFactory);
});
}
}
The ButtonViewDirective is used like helper in our RightPanelComponent just to make much easier to bootstrap custom components: OneComponent, TwoComponent
The RightPanelComponent combines both panels the right and left one for this example. If you want to have them split then the right panel will have the logic of rendering and bootstrapping custom components and the left panel will have the logic of rendering button and trigger changes to the right side components. Communication between Right and Left can be made with an intermediate Service or some kind of events, observables implementation.
Here are some examples of implementation in the official angular doc.
https://angular.io/guide/dynamic-component-loader