Угловой компонент в дочернем окне браузера

Из приложения Angular есть какой-нибудь способ, которым я могу создать дочернее окно браузера и показать в нем некоторый предопределенный угловой компонент.

Пояснение: я не ищу модальное диалоговое решение.

5 ответов

Я попал в этот пост ранее, поэтому, если кто-то все еще пытается визуализировать компонент, динамически загружаемый в разных окнах без запуска нового приложения, я сделал это так:

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');
}

}

Это то, что я нашел для себя, и делает именно то, что вам нужно.

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.

<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 для вашего экземпляра компонента, позволяя вам взаимодействовать с ним из кода.

Если вы используете window.open для дочернего окна, чтобы показать угловой компонент, это окно должно загрузить website в котором используется angular, это означает, что вы можете создать в своем приложении дочерний маршрут, специально предназначенный для этой страницы, и открыть свое приложение для этого конкретного маршрута. Если вы выбрали это решение, знайте о размере вашего приложения, это решение работает нормально, если вы используете асинхронную маршрутизацию, поэтому при открытии приложения в новом окне вы загрузите angular + other core libsкоторый вы используете и + js for that specific route,

Другой вариант заключается в том, что на вашем сервере вы создаете другое угловое приложение, содержащее только этот контент, и у вас есть 2 приложения на одном сервере, которые обслуживаются по разным URL-адресам. В этом случае вам нужно создать новое угловое приложение, которое содержит только этот конкретный контент.

Вы можете сделать это, используя ссылку с target="_blank" атрибут

example.component.html

<a [routerLink]="['/route-to-your-component']" target="_blank">
  Open the component in a new tab
</a>

Создайте ленивый компонент загрузки (как URL) и поместите ваш URL в

window.open('url', 'window name', 'settings')

Вы можете попробовать дать имена своим различным окнам. Это откроет каждое новое окно с указанным именем.

window.open('url', 'window 1', '');
window.open('url', 'window 2', '');
Другие вопросы по тегам