$compile in modern Angular
Angular compiles templates at build time, so there is no way to compile an HTML string at runtime. Dynamic UI is built by choosing among components that already exist.
Before · AngularJS
app.directive('widgetHost', function ($compile) {
return {
scope: { type: '<', data: '<' },
link: function (scope, element) {
var tag = scope.type + '-widget';
var html = '<' + tag + ' data="data"></' + tag + '>';
element.append($compile(html)(scope));
}
};
});After · Angularconst WIDGETS: Record<string, Type<unknown>> = {
chart: ChartWidgetComponent,
table: TableWidgetComponent,
};
@Component({
selector: 'app-widget-host',
imports: [NgComponentOutlet],
template: `<ng-container [ngComponentOutlet]="component()"
[ngComponentOutletInputs]="{ data: data() }" />`,
})
export class WidgetHostComponent {
type = input.required<string>();
data = input<unknown>();
component = computed(() => WIDGETS[this.type()]);
}What changes
- A map from a key to a component class replaces the HTML string built by concatenation.
- NgComponentOutlet renders the chosen component from the template and passes its inputs.
- ViewContainerRef.createComponent does the same from code and returns a ComponentRef, with setInput to pass data.
Migration tip. Find out early if any templates come from a database or a backend response. Those cannot be ported as they are and need a redesign: a fixed set of components driven by data.
Related
Planning a migration or a micro-frontend platform?
In a 20-minute call you describe your situation and I tell you how I'd approach it. If it isn't worth doing yet, I'll say so.
Message me on LinkedIn