【问题标题】:Angular 4 Portal/CdkPortal not working in new child windowAngular 4 Portal/CdkPortal 在新的子窗口中不起作用
【发布时间】:2020-02-12 18:39:03
【问题描述】:

我正在使用 Angular 4 应用程序,我需要在新的子窗口中显示特定组件。所以我研究了一个解决方案(我不是在寻找一个通过 url 路由的解决方案,因为我的服务器总是用 window.open('some URL')重新定向到索引,所以带有附加的 window.open('')可能是解决方案),我找到了这个 stackblitz 示例 StackBlitz Example

在该示例中,正在使用 CdkPortal 。问题显然是 cdk 门户不在 angular 4 中(我不舒尔,但这个错误显示@angular/cdk/portal"' has no exported member 'CdkPortal'

我只是复制并粘贴上一个示例,因为这正是我需要的,但在我的角度版本中不起作用。

是否有 angular 4 的等效示例?

附加

在示例中,他们使用此代码片段来显示窗口

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

所以我的问题是......是否可以在我想在门户中附加的组件内添加其他组件?像这样的。

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

如果可行,该组件会正常工作吗?

【问题讨论】:

  • 你可以在你的组件模板中添加另一个组件,但是你需要使用ng-container指令而不是把它放在窗口组件里面。
  • @Sergio Mendez 你检查过我的回答对你有帮助吗?

标签: angular typescript window portal


【解决方案1】:

试试这个。这将生成一个不使用 CdkPortal 的子窗口。

我使用了通用的 window.open 方法来打开一个新窗口。我也使用了窗口的名称属性来获取打开窗口的引用。

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>

工作示例链接

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

【讨论】:

  • 有什么方法可以将css父样式添加到新创建的窗口中?
  • @Kardon63 您可以将此添加到您的代码中// STEP 5.1: clone stylesheets and style tags to external window document.querySelectorAll('link, style').forEach(htmlElement =&gt; { this.externalWindow.document.head.appendChild(htmlElement.cloneNode(true)); });
  • 好的,这确实是在复制所有样式,但我使用的是第 3 方库devextreem,但是复制到新窗口的样式不会应用于组件。
  • 我在 DynamicWindowComponent 中使用 FormGroup 时遇到错误:17:47 ERROR TypeError: Cannot read property 'get' of undefined at resolveDep (vendor.js:58638) at createClass (vendor.js:) at createDirectiveInstance ( vendor.js:) at createViewNodes (vendor.js:) at createRootView ( vendor.js:) at callWithDebugContext (vendor.js:) at Object.debugCreateRootView [as createRootView] ( vendor.js:) at ComponentFactory_.push../node_modules/@angular/core/fesm5/core.js.ComponentFactory_.create (vendor.js:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 1970-01-01
  • 2017-03-03
  • 2017-12-29
相关资源
最近更新 更多