Это то, что я нашел для себя, и делает именно то, что вам нужно.
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
вместо получения CdkPortal
с помощью @ViewChild
декоратора.Получив ссылку на хост портала, вы даже можете программно заменить содержимое дочернего окна другим компонентом.При подключении портала к узлу портала вы также можете получить ComponentRef
для своего созданного экземпляра компонента, что позволит вам взаимодействовать с ним из кода.