Sergio Mendez
Sergio Mendez

Reputation: 1519

Angular 4 Portal/CdkPortal not working in new child window

I'm working in an Angular 4 app and I need to show a specific component in a new child window. So I research for a solution (i'm NOT looking for a solution with routing by url 'couse my server always redirec to index with window.open('some URL'), so window.open('') with ataching might be the solution) and I found this stackblitz example StackBlitz Example

in that example, are using CdkPortal . The problem is apparently cdk portal is not in angular 4 (I'm not shure, but this error is showing @angular/cdk/portal"' has no exported member 'CdkPortal')

I just copy and paste the previous example 'couse is exactly what I need, but in my angular version is not working.

Is there some equivalent example for angular 4?

ADITIONAL

in the example, they are using this code fragment to show the window

<window *ngIf="showPortal">
  <h2>Hello world from amother window!!</h2>
  <button (click)="this.showPortal = false">Close me!</button>
</window>

so my question is... is posible to add other component inside the component that I want to atach in the portal? Something like this.

<window *ngIf="showPortal">
  <my-other-component [currentValue]="someValue"></my-other-component>
</window>

If it is posible, Would the component work correctly?

Upvotes: 3

Views: 2212

Answers (1)

Passionate Coder
Passionate Coder

Reputation: 7294

Try this. This will generate a child window without use of CdkPortal.

I have used generic window.open method to open a new window. also i have used name property of window to get reference of opened window.

app.component.ts

import { Component,ComponentFactoryResolver, ViewChild, ViewContainerRef,Injector } from '@angular/core';
import { DynamicWindowComponent } from './dynamic-window/dynamic-window.component';


@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  injector: Injector;
  OpenWindow : any

  constructor(private resolver: ComponentFactoryResolver) { }

  open(): void {
    const componentFactory = this.resolver.resolveComponentFactory(DynamicWindowComponent);
    let componentRef  = componentFactory.create(this.injector);
    this.OpenWindow = window.open('', 'childwindow', 'width=400,height=400,left=150,top=200');
    this.OpenWindow.document.body.innerHTML = "";
    this.OpenWindow.document.body.appendChild(componentRef.location.nativeElement);
  }

  close(){
    this.OpenWindow.close()
  }
}

app.component.html

<button (click)="open()">Dynamically Add Component</button>

dynamic-window.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-dynamic-window',
  templateUrl: './dynamic-window.component.html',
  styleUrls: ['./dynamic-window.component.css']
})
export class DynamicWindowComponent{
  close(){
    // get refence of child window by its name and close it
    let existingWin = window.open('', 'childwindow');
    existingWin.close();
  }
}

dynamic-window.component.html

<p>Dynamic Component</p>
 <button (click)="close()">Close me!</button>

Working example link

https://stackblitz.com/edit/angular-rbapx4?embed=1&file=src/app/app.component.ts

Upvotes: 1

Related Questions