Angular 2 模态在组件之间共享 [英] Angular 2 modals shared between components
问题描述
我有一个包含许多组件的典型 Angular 2 应用程序.
我安装了这个模态组件:https://github.com/pleerock/ng2-modal.
有没有办法在更多组件之间共享相同的模态?我解释得更好.我希望单击不同组件内的不同按钮时应该打开相同的模式.是否可以?
我尝试过这种方法https://plnkr.co/edit/RgI1e9PobC7FloLHpEFD?p=preview但这不是正确的方法,因为它总是向模态框添加内容.
我把它贴在我的 app.ts 文件下面:
21/12/2016 更新
根据@echonax 的建议,我更新了我的 plunk:
//我们的根应用组件进口 {Ng模块,组件参考,可注射,零件,注射器,ViewContainerRef,ViewChild, ComponentFactoryResolver} 来自@angular/core";从@angular/platform-browser"导入 {BrowserModule}从'rxjs/Subject'导入{Subject};@Injectable()导出类共享服务 {showModal:主题<any>= 新主题();}@零件({选择器:'子组件',模板:`<button (click)="showDialog()">从孩子显示模态</button>`,})导出类子组件 {构造函数(私有共享服务:共享服务){}显示对话(){this.sharedService.showModal.next(CompComponent);}}@零件({选择器:'comp-comp',模板:`我的组件`})导出类 CompComponent { }@零件({选择器:'modal-comp',模板:`<div class="modal fade" id="theModal" tabindex="-1" role="dialog" aria-labelledby="theModalLabel"><div class="modal-dialog largeWidth"角色="文档"><div class="模态内容"><div class="modal-header"><h4 class="modal-title" id="theModalLabel">标签</h4></div><div class="modal-body" #theBody></div><div class="模态页脚"><button type="button" class="btn btn-default" data-dismiss="modal" (close)="close()">关闭</button></div></div></div></div>`})导出类 ModalComponent {@ViewChild('theBody', {read: ViewContainerRef}) theBody;cmp:ComponentRef<any>;cmpRef:ComponentRef<any>;构造函数(共享服务:共享服务,私有componentFactoryResolver:ComponentFactoryResolver,喷油器:喷油器){sharedService.showModal.subscribe(type => {如果(这个.cmp){this.cmp.destroy();}让工厂 = this.componentFactoryResolver.resolveComponentFactory(type);this.cmpRef = this.theBody.createComponent(工厂)$('#theModal').modal('show');});}关闭() {如果(这个.cmp){this.cmp.destroy();}这个.cmp = null;}}@零件({选择器:'我的应用',模板:`<h2>你好</h2><button(click)="showDialog()">显示模态</button><子组件></子组件></div>`,})导出类 App {构造函数(私有共享服务:共享服务){}显示对话(){this.sharedService.showModal.next(CompComponent);}}@NgModule({进口:[浏览器模块],声明:[App, ModalComponent, CompComponent, ChildComponent],提供者:[SharedService],entryComponents:[CompComponent],引导程序:[应用程序,模态组件]})导出类 AppModule{}敬请期待!
解决方案 那个 plunker 的原始版本实际上是我的问题:如何动态创建引导模式作为Angular2组件?
@Günter 给出了一个惊人的答案,我认为这确实被低估了.
plunker有一个小错误,你可以在这里找到修复版本:https://plnkr.co/edit/oMCZIJq58WdLgYf2D0Di?p=preview
if 案例引用了错误的字段,所以改变
if(this.cmp) {this.cmp.destroy();}
与
if(this.cmpRef) {this.cmpRef.destroy();}
I have a typical Angular 2 app with many components.
I installed this modal component: https://github.com/pleerock/ng2-modal.
Is there a way to share the same modals between more components?
I explain better. I would like the same modal should open on click of different buttons inside different components. Is it possible?
I tried this kind of approach
https://plnkr.co/edit/RgI1e9PobC7FloLHpEFD?p=preview
but it's not the right way, because it always adds content to the modal.
I post it here below my app.ts file:
21/12/2016 update
Following @echonax suggestion, I updated my plunk:
//our root app component
import {
NgModule,
ComponentRef,
Injectable,
Component,
Injector,
ViewContainerRef,
ViewChild, ComponentFactoryResolver} from "@angular/core";
import {BrowserModule} from '@angular/platform-browser'
import {Subject} from 'rxjs/Subject';
@Injectable()
export class SharedService {
showModal:Subject<any> = new Subject();
}
@Component({
selector: 'child-component',
template: `
<button (click)="showDialog()">show modal from child</button>
`,
})
export class ChildComponent {
constructor(private sharedService:SharedService) {}
showDialog() {
this.sharedService.showModal.next(CompComponent);
}
}
@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 {
@ViewChild('theBody', {read: ViewContainerRef}) theBody;
cmp:ComponentRef<any>;
cmpRef:ComponentRef<any>;
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;
}
}
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello</h2>
<button (click)="showDialog()">show modal</button>
<child-component></child-component>
</div>
`,
})
export class App {
constructor(private sharedService:SharedService) {}
showDialog() {
this.sharedService.showModal.next(CompComponent);
}
}
@NgModule({
imports: [ BrowserModule ],
declarations: [ App, ModalComponent, CompComponent, ChildComponent],
providers: [SharedService],
entryComponents: [CompComponent],
bootstrap: [ App, ModalComponent ]
})
export class AppModule{}
Stay tuned!
解决方案 That plunker's original version is my question actually: How to dynamically create bootstrap modals as Angular2 components?
@Günter made an amazing answer which I think is really underrated.
The plunker has a small mistake, you can find the fixed version here: https://plnkr.co/edit/oMCZIJq58WdLgYf2D0Di?p=preview
The if cases are referencing the wrong field, so change
if(this.cmp) {
this.cmp.destroy();
}
with
if(this.cmpRef) {
this.cmpRef.destroy();
}
这篇关于Angular 2 模态在组件之间共享的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文