如何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处理,也不会导致组件或指令被实例化或添加。
您不能使用 (不build议使用) DynamicComponentLoader
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); } }