我正在用ngComponentOutlet动态创建一个组件。 听起来像是:
import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
@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...';
}
@Component({
selector: 'my-app',
template: `
<h1>Angular version 4</h1>
<ng-container *ngComponentOutlet="alert"></ng-container>
<button (click)="changeComponent()">Change component</button>
`,
})
export class App {
alert = AlertSuccessComponent;
changeComponent() {
this.alert = AlertDangerComponent;
alert(this.alert.test); <-- ???????
}
}
@NgModule({
imports: [ BrowserModule ],
declarations: [ App, AlertSuccessComponent, AlertDangerComponent ],
entryComponents: [AlertDangerComponent, AlertSuccessComponent],
bootstrap: [ App ]
})
export class AppModule {}
在changeComponent()中,我尝试(天真地猜测)获取当前组件的引用以用数据提供它,但它失败了:(
我是否必须使用ViewContainerRef,怎么做?
答案 0 :(得分:1)
您必须直接将组件名称放在那里:
<ng-container *ngComponentOutlet="AlertDangerComponent;
ngModuleFactory: alertDangerModule;"></ng-container>
我冒昧地添加了模块,用于从不同于当前模块的模块渲染组件时。
另外,对于使用Module选项,您需要在当前组件中使用它:
private alertDangerModule: NgModuleFactory<any>;
constructor(private compiler: Compiler) {
this.alertDangerModule = compiler.compileModuleSync(AlertDangerModule);
}
如果您只想从当前模块加载1个组件,则需要执行以下操作:
<ng-container *ngComponentOutlet="AlertDangerComponent"></ng-container>
导入模块:NgModuleFactory
更新(动态):
创建一个向量,例如:
import AlertDangerComponent from './path';
import AlertSuccessComponent from './path';
export const MY_ALERTS = {
'alertDanger': AlertDangerComponent,
'alertSuccess': AlertSuccessComponent,
};
在您的组件中,您导入MY_ALERTS
,并且可以呈现与MY_ALERTS
一样多的组件。
或者您可以尝试动态渲染它,方法是创建一个新的ng-container
(尚未测试)。
我正在使用它来渲染包含其他值(如布尔值)的组件类的大型向量中的组件,因此我知道每次加载哪个组件。
要渲染此向量中的组件,您可以:
<div *ngFor="let alert of MY_ALERTS | keys">
<ng-container *ngComponentOutlet="MY_ALERTS[alert];
ngModuleFactory: commonAlertsModule;"></ng-container>
</div>
keys
只是一个@Pipe
,它返回一个对象的键(而不是值)。
更新(替代方法):
我在想,也许你可能对这个其他方法感兴趣:使用@Component作为'Directive'。我会自己解释一下:
使用指令声明您的组件,如选择器:
@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...';
}
然后,根据场合,您只需拨打一个或另一个:
@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;
}
}
在我的示例中(未经过测试)我初始化成功提醒。点击后,它应将alertSuccess
设置为false
并将alertDanger
设置为true
。
答案 1 :(得分:0)
我遇到了同样的问题,并且做了一些阅读。 Angular世界瞬息万变。在撰写本文时,这似乎是Angular指南中最正式的方法。请参阅此食谱食谱:
Angular Dynamic Component Loader
它使用“ anchor”指令来告诉Angular动态组件在模板中的位置。然后继续使用组件工厂和视图容器ref来创建和插入动态组件,同时保存新添加的组件的实例。