在Angular应用程序中,有没有办法创建浏览器的子窗口并在其中显示预定义的Angular组件。
澄清:我不是在寻找模态对话框解决方案。
在Angular应用程序中,有没有办法创建浏览器的子窗口并在其中显示预定义的Angular组件。
澄清:我不是在寻找模态对话框解决方案。
我之前也遇到过这样的问题,如果有人仍在尝试在不运行新应用程序的情况下动态加载不同窗口上的组件,则可以按照以下方式进行操作:
export class ChildLoaderComponent implements OnInit, AfterViewInit {
constructor(private r: ComponentFactoryResolver, private
viewContainerRef: ViewContainerRef) { }
public windowReference: any;
ngAfterViewInit() {
setTimeout(() => {
//create the component dynamically
const factory = this.r.resolveComponentFactory(AChildComponent);
const comp: ComponentRef<AChildComponent> =
this.viewContainerRef.createComponent(factory);
//in case you also need to inject an input to the child,
//like the windows reference
comp.instance.someInputField = this.windowReference.document.body;
//add you freshly baked component on the windows
this.windowReference.document.body.appendChild(comp.location.nativeElement);
});
}
ngOnInit() {
//create the windows and save the reference
this.windowReference = window.open('', '_blank', 'toolbar=0, width=800, height=400');
}
}
document.querySelectorAll('link, style').forEach((htmlElement) => {
if (this.windowReference) {
this.windowReference.document.head.appendChild(htmlElement.cloneNode(true));
}
});
这样你就可以将你的样式附加到窗口中并且它们应该会被加载。 - RowdyArg这就是我为自己找到的,完全符合你所需。
https://stackblitz.com/edit/angular-open-window
可以在新的子窗口中显示自定义的Angular组件,任何Angular服务也将注入到在子窗口中显示的任何组件中。WindowComponent
,其中包含一个门户主机。该门户主机附加到子窗口的主体上。这意味着附加到门户主机的任何门户都将呈现到子窗口的主体上。通过门户主机传递componentFactoryResolver
、applicationRef
和injector
,可能是为了初始化您的自定义Angular组件并在子窗口中注入所需的服务。const host = new DomPortalHost(
this.externalWindow.document.body,
this.componentFactoryResolver,
this.applicationRef,
this.injector
);
WindowComponent
的模板中,它使用*cdkPortal
定义了一个门户。在门户内部,它使用ng-content
投射了窗口组件的内容,该内容由窗口内容的父级定义。请注意保留HTML标签。<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>
ComponentPortal
而不是使用@ViewChild
装饰器检索CdkPortal
来以编程方式创建子窗口。通过检索对门户主机的引用,您甚至可以以编程方式使用不同的组件替换子窗口的内容。将门户连接到门户主机时,您还可以获取实例化组件的ComponentRef
,从代码中与其交互。window.open
打开子窗口来展示Angular组件,那么该窗口应该加载一个使用Angular的website
,这意味着您可以为该页面创建一个专门的子路由,并将您自己的应用程序打开到该特定路由。如果您选择此解决方案,请注意您的应用程序大小,如果您使用异步路由,则此解决方案将有效,因此当您在新窗口中打开应用程序时,您将下载所使用的angular
+ 其他核心库
以及该特定路由的js文件
。target="_blank"
属性的链接来实现此功能。
example.component.html
<a [routerLink]="['/route-to-your-component']" target="_blank">
Open the component in a new tab
</a>
您可以尝试为不同的窗口命名。这将使用指定的名称打开每个新窗口。
window.open('url', 'window 1', '');
window.open('url', 'window 2', '');
window.open('url', 'window name', 'settings')
<a target="_blank" routerLink="/SomeValidRoute">
- dmcgrandle