You have to put the component name directly there:
<ng-container *ngComponentOutlet="AlertDangerComponent;
ngModuleFactory: alertDangerModule;"></ng-container>
I took the liberty to add the Module, is used for when you render a component from a Module different from the current Module.
Also, for using the Module option, you'll need this in your current component:
private alertDangerModule: NgModuleFactory<any>;
constructor(private compiler: Compiler) {
this.alertDangerModule = compiler.compileModuleSync(AlertDangerModule);
}
If you just want to load 1 component from current Module, this is what you need to do:
<ng-container *ngComponentOutlet="AlertDangerComponent"></ng-container>
NgComponentOutlet
For importing Module: NgModuleFactory
Update (Dynamic):
Create a vector, such as:
import AlertDangerComponent from './path';
import AlertSuccessComponent from './path';
export const MY_ALERTS = {
'alertDanger': AlertDangerComponent,
'alertSuccess': AlertSuccessComponent,
};
In your component, you import MY_ALERTS
, and you could render as many components as MY_ALERTS
has.
Or you could try render it dynamically, by creating a new ng-container
(Haven't test this yet).
I'm using this to render components from a huge vector containing component classes with other values such as booleans so I know which component to load each time.
To render a component that is inside this vector you can:
<div *ngFor="let alert of MY_ALERTS | keys">
<ng-container *ngComponentOutlet="MY_ALERTS[alert];
ngModuleFactory: commonAlertsModule;"></ng-container>
</div>
Where keys
is just a @Pipe
that returns me the keys of an object (instead of the value).
Update (Alternative approach):
I was thinking that maybe you could be interested on this other approach: Use a @Component as a 'Directive'. I'll explain myself:
Declare your Components with a directive like selector:
@Component({
selector: '[alert-success]',
template: `
<p>Alert success</p>
`,
})
export class AlertSuccessComponent { }
@Component({
selector: '[alert-danger]',
template: `
<p>Alert danger</p>
`,
})
export class AlertDangerComponent {
test = 'danger...';
}
Then, you just call one or the other, depending on occasion:
@Component({
selector: 'my-app',
template: `
<h1>Angular version 4</h1>
<div *ngIf="alertDanger" alert-danger></div>
<div *ngIf="alertSuccess" alert-success></div>
<button (click)="changeComponent()">Change component</button>
`,
})
export class App {
alertSuccess = true;
alertDanger = false;
changeComponent() {
this.alertSuccess = !this.alertSuccess;
this.alertDanger = !this.alertDanger;
}
}
In my example (not tested though) I initialize the Success Alert. On click, It should set alertSuccess
as false
and set alertDanger
as true
.