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

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

Уточнение: я не ищу решение для модального диалога.

Ответ 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>