Угловой компонент в дочернем окне браузера
Из Углового приложения есть способ, которым я могу создать дочернее окно браузера и показать в нем предопределенный угловой компонент.
Уточнение: я не ищу решение для модального диалога.
Ответы
Ответ 1
В случае, если вы используете window.open
для дочернего окна, чтобы показать угловой компонент, в этом окне должно загружаться website
использующий угловой. Это означает, что вы легко создадите в своем приложении дочерний маршрут, специально для этой страницы, и откроете свое собственное приложение. к этому конкретному маршруту. Если вы выбрали это решение, знайте о размере вашего приложения, оно будет работать нормально, если вы используете асинхронную маршрутизацию, поэтому при открытии приложения в новом окне вы загрузите angular
+ other core libs
которые вы используете, и + js for that specific route
.
Другой вариант заключается в том, что на вашем сервере вы создаете другое угловое приложение, содержащее только этот контент, и у вас есть 2 приложения на одном сервере, которые обслуживаются по разным URL-адресам. В этом случае вам нужно создать новое угловое приложение, которое содержит только этот конкретный контент.
Ответ 2
Я попал в этот пост ранее, поэтому, если кто-то все еще пытается визуализировать компонент, динамически загружаемый в разных окнах без запуска нового приложения, я сделал это следующим образом:
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');
}
}
Ответ 3
Это то, что я нашел для себя, и делает именно то, что вам нужно.
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
для вашего оконного компонента, и *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
декоратора @ViewChild
. Получив ссылку на хост портала, вы даже можете программно заменить содержимое дочернего окна другим компонентом. При подключении портала к узлу портала вы также можете получить ComponentRef
для своего созданного экземпляра компонента, что позволит вам взаимодействовать с ним из кода.
Ответ 4
Вы можете попробовать дать имена своим различным окнам. Это откроет каждое новое окно с указанным именем.
window.open('url', 'window 1', '');
window.open('url', 'window 2', '');
Ответ 5
Создайте ленивый компонент загрузки (как URL) и поместите ваш URL в
window.open('url', 'window name', 'settings')
Ответ 6
Вы можете сделать это, используя ссылку с атрибутом target="_blank"
example.component.html
<a [routerLink]="['/route-to-your-component']" target="_blank">
Open the component in a new tab
</a>