这是我为自己找到的,并且完全符合您的需要。
https://stackblitz.com/edit/angular-open-window
可以在新的子窗口中显示您的自定义角度组件,并且任何角度服务也将被注入到子窗口中显示的任何组件中。
它定义了一个新的WindowComponent,其中包含一个门户主机。此门户主机附加到子窗口的主体。这意味着附加到门户主机的任何门户都将呈现到子窗口的主体。向门户主机传递componentFactoryResolver、applicationRef 和injector,大概是为了初始化您的自定义角度组件并在子窗口中注入所需的服务。
const host = new DomPortalHost(
this.externalWindow.document.body,
this.componentFactoryResolver,
this.applicationRef,
this.injector
);
在WindowComponent 的模板中,它使用*cdkPortal 定义了一个门户。在门户内部,它使用 ng-content 投影窗口组件的内容,由窗口内容的父级定义。
<ng-container *cdkPortal>
<ng-content></ng-content>
</ng-container>
无论何时创建WindowComponent,它都会打开一个子窗口,并将其门户附加到门户主机。当WindowComponent被销毁时,会关闭子窗口。
ngOnInit(){
// STEP 4: create an external window
this.externalWindow = window.open('', '', 'width=600,height=400,left=200,top=200');
// STEP 5: create a PortalHost with the body of the new window document
const host = ...
// STEP 6: Attach the portal
host.attach(this.portal);
}
ngOnDestroy(){
// STEP 7: close the window when this component destroyed
this.externalWindow.close()
}
这意味着在应用程序组件中,您可以使用窗口组件上的*ngIf 指令简单地切换弹出窗口,并嵌套您想要在模板中显示的任何内容。
<window *ngIf="showPortal">
<h2>Hello world from another window!!</h2>
<button (click)="this.showPortal = false">Close me!</button>
</window>
使用@angular/cdk 包,您还可以修改此示例以编程方式创建子窗口,方法是使用ComponentPortal 而不是使用@ViewChild 装饰器检索CdkPortal。通过检索对门户主机的引用,您甚至可以以编程方式将子窗口的内容替换为不同的组件。将门户附加到门户主机时,您还可以为您的实例化组件获取ComponentRef,从而允许您通过代码与之交互。