如何dynamic创build引导模式作为Angular2组件?

原始标题 :无法在Angular 2中初始化dynamic附加(HTML)组件

我创build了一个指令,在初始化时将模态添加到主体。 当一个button(注入了指令)被点击时,这个模式启动。 但我希望这个模式的内容是另一个组件(事实上,我希望模态是组件)。 看来我无法初始化组件。

这是我所做的一件事:

http://plnkr.co/edit/vEFCnVjGvMiJqb2Meprr?p=preview

我试图让我的组件模板

'<div class="modal-body" #theBody>' + '<my-comp></my-comp>' + '</div> 

更新为2.0.0最后

Plunker示例> = 2.0.0

 @NgModule({ imports: [ BrowserModule ], declarations: [ App, ModalComponent, CompComponent], providers: [SharedService], entryComponents: [CompComponent], bootstrap: [ App, ModalComponent ] }) export class AppModule{} 
 export class ModalComponent { @ViewChild('theBody', {read: ViewContainerRef}) theBody; cmp:ComponentRef; constructor( sharedService:SharedService, private componentFactoryResolver: ComponentFactoryResolver, injector: Injector) { sharedService.showModal.subscribe(type => { if(this.cmp) { this.cmp.destroy(); } let factory = this.componentFactoryResolver.resolveComponentFactory(type); this.cmpRef = this.theBody.createComponent(factory) $('#theModal').modal('show'); }); } close() { if(this.cmp) { this.cmp.destroy(); } this.cmp = null; } } 

暗示

如果一个应用程序改变SharedService的状态,或者调用一个使Observable发出一个值的方法,并且用户在不同的应用程序中,那么发射器中的用户代码就在发射器的NgZone中执行。

所以在订阅SharedService使用observable

 class MyComponent { constructor(private zone:NgZone, private sharedService:SharedService) { private sharedService.subscribe(data => this.zone.run() => { // event handler code here }); } } 

有关如何触发更改检测的更多详细信息,请参阅手动触发Angular2更改检测

原版的

dynamic添加的HTML不会被Angular处理,也不会导致组件或指令被实例化或添加。

您不能使用DynamicComponentLoader (不build议使用) ViewContainerRef.createComponent() ( Angular 2dynamic选项卡和用户单击选定组件 )在Angulars根组件(AppComponent)之外添加组件。

我猜最好的办法是在Angulars之外创build第二个组件,在每个组件上调用bootstrap()并使用共享服务进行通信:

 var sharedService = new SharedService(); bootstrap(AppComponent, [provide(SharedService, {useValue: sharedService})]); bootstrap(ModalComponent, [provide(SharedService, {useValue: sharedService})]); 

Plunker示例beta.17
Plunker示例beta.14

 @Injectable() export class SharedService { showModal:Subject = new Subject(); } @Component({ selector: 'comp-comp', template: `MyComponent` }) export class CompComponent { } @Component({ selector: 'modal-comp', template: ` <div class="modal fade" id="theModal" tabindex="-1" role="dialog" aria-labelledby="theModalLabel"> <div class="modal-dialog largeWidth" role="document"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title" id="theModalLabel">The Label</h4></div> <div class="modal-body" #theBody> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal" (close)="close()">Close</button> </div></div></div></div> ` }) export class ModalComponent { cmp:ComponentRef; constructor(sharedService:SharedService, dcl: DynamicComponentLoader, injector: Injector, elementRef: ElementRef) { sharedService.showModal.subscribe(type => { if(this.cmp) { this.cmp.dispose(); } dcl.loadIntoLocation(type, elementRef, 'theBody') .then(cmp => { this.cmp = cmp; $('#theModal').modal('show'); }); }); } close() { if(this.cmp) { this.cmp.dispose(); } this.cmp = null; } } @Component({ selector: 'my-app', template: ` <h1>My First Attribute Directive</h1> <button (click)="showDialog()">show modal</button> <br> <br>`, }) export class AppComponent { constructor(private sharedService:SharedService) {} showDialog() { this.sharedService.showModal.next(CompComponent); } }