angular6 - ngx bootstrap - 在模板中嵌套组件
问题描述
我们的应用程序中有一个标准模式。
<ng-template [ngIf]="true" #editDataModal>
<div class="modal-header">
<h5 class="modal-title">Edit Modal</h5>
<button type="button" class="close" aria-label="Close" (click)="onCancelClicked()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" #editDataModalBody>CUSTOM COMPONENT GOES HERE</div>
</ng-template>
我们希望能够传入一个自定义组件作为我们的 body。ngx bootstrap 有没有办法做到这一点?
模态似乎出现在主要内容之外,因此我们无法使用 ViewChild 找到它。
我们使用模态服务调用它。像这样:-
constructor(
private modalService: BsModalService
) { }
ngOnInit() {
this.modalConfig = {
ignoreBackdropClick: true
};
this.ModalRef = this.modalService.show(this.editModal, this.modalConfig);
}
解决方案
模态组件可以获取并发布 ViewContainerRef。例如,它可以使用 BehaviorSubject。父组件可以创建自定义组件,并在 viewContainerRef 发布时将其添加到 modal 中。我只是这样做,而不仅仅是一个吸气剂,因为 ViewChild 在 afterViewInit 之前是无效的,所以你需要一种方法来处理它。
// EditModalComponent
export class EditModalComponent implements AfterViewInit {
@ViewChild("editDataModalBody", {read: ViewContainerRef}) vc: ViewContainerRef;
public bodyRefSubject: BehaviorSubject<ViewContainerRef> = new BehaviorSubject<ViewContainerRef>(null);
constructor(
public bsModalRef: BsModalRef,
public vcRef: ViewContainerRef
) {}
ngAfterViewInit() {
this.bodyRefSubject.next(this.vc);
}
onCancelClicked() {
console.log('cancel clicked');
this.bsModalRef.hide()
}
}
在父组件中:
// Parent Component
export class AppComponent {
bsModalRef: BsModalRef;
bodyContainerRef: ViewContainerRef;
customComponentFactory: ComponentFactory<CustomComponent>;
modalConfig: ModalOptions;
constructor(
private modalService: BsModalService,
private resolver: ComponentFactoryResolver
) {
this.customComponentFactory = resolver.resolveComponentFactory(CustomComponent);
}
openModalWithComponent() {
this.modalConfig = {
ignoreBackdropClick: true,
}
this.bsModalRef = this.modalService.show(EditModalComponent, this.modalConfig);
this.bsModalRef.content.bodyRefSubject.subscribe((ref) => {
this.bodyContainerRef = ref;
if (this.bodyContainerRef) {
this.bodyContainerRef.createComponent(this.customComponentFactory);
}
})
}
}
不使用 ViewChild 的另一种方法是在 div 上放置一个指令而不是 #editDataModalBody 并且该指令可以注入 ViewContainerRef 并使用服务或类似的方式发布它。
推荐阅读
- ubuntu - Yocto Project: Ubuntu 16.04 LTS keeps crashing when running: bitbake fsl-image-gui
- python - 在 Python 中测量串行 Tx 和 Rx 之间的时间间隔
- arrays - 机器学习的数据形状
- scala - 如何取消旋转大型 Spark 数据框?
- mapbox - Mapbox - 是什么决定了国家标签显示在哪个缩放级别?
- python - 如何计算 .txt 中的多个输入,而不仅仅是一个
- sql - 更新 SQL Server 中 GROUP BY sum() 函数的查询问题
- reactjs - 向子组件添加道具
- arrays - Perl:强制按数字顺序散列
- swiftui - VStack 中的 NavigationLink 在 iPad 上已损坏