如何订阅通过@angular/cdk/portal注入的组件的Observable?

2023-12-08

我正在尝试实现一个基本的(非常基本的)模式实现。我有一个ModalService and a ModalComponent.

The ModalService创建一个实例ModalComponent并使用 @angular/cdk/portal 将其注入页面。

我可以让模态显示得很好:-)

The ModalComponent有一个我想要的 Observable 属性ModalService订阅,以便当在模式中单击“关闭”按钮时,可以发出一个值并且ModalService可以关闭模​​态框。

但是,当组件发出该值时,服务不会对其进行操作。从服务端来看,看起来我已经订阅了,但从组件端来看,它显示了 0 个观察者。

我想也许我可以使用一个典型的@Output()EventEmitter,但我不确定自模式类中以来是否将其连接起来,因为子元素最初不存在。

我想也许我的组件参考不太正确(也许我有两个不同的?)。我正在尝试来自的建议这个答案

有什么想法我做错了吗?

Service

export class ModalService {

    private modalPortal: ComponentPortal<any>;
    private bodyPortalHost: DomPortalHost;

    constructor(private componentFactoryResolver: ComponentFactoryResolver,
                private appRef: ApplicationRef,
                private injector: Injector) {
    }

    showModal(modalName: string) {

        // set up the portal and portal host
        this.modalPortal = new ComponentPortal(ModalComponent);
        this.bodyPortalHost = new DomPortalHost(
            document.body,
            this.componentFactoryResolver,
            this.appRef,
            this.injector);

        // display the component in the page
        let componentRef = this.bodyPortalHost.attach(this.modalPortal);


        // listen for modal's close event
        componentRef.instance.onModalClose().subscribe(() => {
            console.log('I will be very happy if this this gets called, but it never ever does');
            this.closeModal();
        });

        // console.log(componentRef.instance.onModalClose()) shows 1 subscriber.
    }

    closeModal() {
        this.bodyPortalHost.detach();
    }
}

成分

export class ModalComponent {

    private modalClose: Subject<any> = new Subject();

    onModalClose(): Observable<any> {
        return this.modalClose.asObservable();
    }

    closeModal() {
        // console.log(this.onModalClose()) **shows zero observers**   :-(
        this.modalClose.next();
        this.modalClose.complete();
    }
}

另外,如果我碰巧问错了问题,意味着有更好的整体方法,我愿意接受建议。 :-)

Thanks!


这段代码对我来说只需要很少的更改,所以我对你的问题是什么感到困惑。首先,我使用 Angular CLI 创建了一个项目ng new。然后我使用安装了 ng 材料他们网站上的说明.

我创建了一个与您的服务相同的模态服务:

    import {ApplicationRef, ComponentFactoryResolver, Injectable, Injector} from '@angular/core';
import {DomPortalHost, ComponentPortal} from "@angular/cdk/portal";
import {ModalComponent} from "./modal/modal.component";

@Injectable({
  providedIn: 'root'
})
export class ModalService {

  private modalPortal: ComponentPortal<any>;
  private bodyPortalHost: DomPortalHost;

  constructor(private componentFactoryResolver: ComponentFactoryResolver,
              private appRef: ApplicationRef,
              private injector: Injector) {
  }

  showModal(modalName: string) {

    // set up the portal and portal host
    this.modalPortal = new ComponentPortal(ModalComponent);
    this.bodyPortalHost = new DomPortalHost(
      document.body,
      this.componentFactoryResolver,
      this.appRef,
      this.injector);

    // display the component in the page
    let componentRef = this.bodyPortalHost.attach(this.modalPortal);


    // listen for modal's close event
    componentRef.instance.onModalClose().subscribe(() => {
      console.log('I will be very happy if this this gets called, but it never ever does');
      this.closeModal();
    });

    // console.log(componentRef.instance.onModalClose()) shows 1 subscriber.
  }

  closeModal() {
    this.bodyPortalHost.detach();
  }
}

我创建了一个模态组件。 TypeScript 与你的相同:

import { Component, OnInit } from '@angular/core';
import {Observable, Subject} from "rxjs/index";

@Component({
  selector: 'app-modal',
  templateUrl: './modal.component.html',
  styleUrls: ['./modal.component.css']
})
export class ModalComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

  private modalClose: Subject<any> = new Subject();

  onModalClose(): Observable<any> {
    return this.modalClose.asObservable();
  }

  closeModal() {
    // console.log(this.onModalClose()) **shows zero observers**   :-(
    this.modalClose.next();
    this.modalClose.complete();
  }

}

您没有给我们 HTML 模型,但这是我使用的:

<p>
  modal works!
</p>
<button (click)="closeModal()">Close Modal</button>

这是我的 app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';

import { AppComponent } from './app.component';
import {ModalService} from "src/app/modal.service";
import { ModalComponent } from './modal/modal.component';

@NgModule({
  declarations: [
    AppComponent,
    ModalComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule
  ],
  providers: [ModalService],
  bootstrap: [AppComponent],
  entryComponents: [ModalComponent]
})
export class AppModule { }

注意我在entryComponents 中定义了ModalComponent,并将ModalService 定义为提供者。

应用程序组件 HTML:

<button (click)="showModal()">Show Modal</button>

和 app.component 打字稿:

import { Component } from '@angular/core';
import {ModalService} from "./modal.service";
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  constructor(public modalService: ModalService){}

  showModal(){
       this.modalService.showModal("This is the modal name");
  }

}

我将 ModalService 注入到构造函数中,并调用 showModal 方法来响应主应用程序中的按钮单击。

Load the app: Initial App Load

单击该按钮,将显示模式。它看起来不像模态,但这可能是因为缺少样式:

App with Modal Shown

现在单击模式内的关闭按钮:

Modal Closed

您会看到模式消失,控制台输出显示您的消息。

这篇文章可以帮助您找到您错过的花絮吗?


要补充一件事。如果要将数据从模态发送到调用它的组件,必须更改模型组件 close Modal 方法:

  closeModal() {
    // console.log(this.onModalClose()) **shows zero observers**   :-(
    this.modalClose.next('Your Data Here, it can be an object if need be');
    this.modalClose.complete();
  }

并且您的模态服务可以访问中的数据onModalClose().subscribe() method:

componentRef.instance.onModalClose().subscribe((results) => {
  console.log(results);
  console.log('I will be very happy if this this gets called, but it never ever does');
  this.closeModal();
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何订阅通过@angular/cdk/portal注入的组件的Observable? 的相关文章

随机推荐

  • 使用对话框时背景模糊

    我希望对话框后面的背景变得模糊 我使用了这段代码 但它使整个背景变黑而不是模糊 dialog new Dialog context R style Theme Dialog Translucent dialog requestWindowF
  • Rails 3.2.4 SQL 查询在 find(:all) 上缓存结果

    我不完全确定该系统是否正在缓存数据 但它具有一些缓存特征 基本上我在搞乱 Rails 3 2 4 系统开始不显示一些结果 我认为这与我放入代码模型中的默认范围有关 但即使如此 这也应该显示所有结果 而不是十分之九 但是 我总是会丢失我创建的
  • 如何使用 Python 3.5 和 BeautifulSoup 抓取 href [重复]

    这个问题在这里已经有答案了 我想从网站上抓取每个项目的 href使用 Python 3 5 和 BeautifulSoup 这是我的代码 Loading Libraries import urllib import urllib reque
  • Google Maps API v3:自定义标记在移动设备上不可点击

    我们有一个网站 它使用 Google Maps API v3 在地图上显示一堆标记 这些标记是可点击的 并打开一个标准的谷歌地图信息弹出窗口 这在所有桌面浏览器上都非常有效 但由于某种原因 我无法让它在我测试过的任何移动设备 各种 Andr
  • jquery多维数组随机洗牌

    我想最小化我的代码 myArrayA 1 2 3 4 5 fisherYates myArrayA myArrayB 6 7 8 9 10 fisherYates myArrayB myArrayC 11 12 13 14 15 fishe
  • 我们可以在finally块中使用“return”吗[重复]

    这个问题在这里已经有答案了 我们可以使用 return 语句吗finally堵塞 这会导致任何问题吗 从a内返回finally阻塞会导致exceptions丢失 finally 块内的 return 语句将导致 try 或 catch 块中
  • OSX 以编程方式调用声级图形

    我有一个可以在 OSX 下更改音量的应用程序 它缺少的是按下声音上 下键时提供的视觉反馈 有谁知道如何以编程方式调用该行为 谢谢 以下是 George Warner 和 Casey Fleser 编写的一些代码 用于实现此目的 仔细想想这是
  • 对 Java 中另一个类中实例化/初始化的对象的引用变量

    我问的原因是因为我收到 NullPointerException 我现在这很容易 但我是一个相当新的编程人员 发现这有点令人困惑 假设我已经初始化了一个类中的一个对象 并且想要从另一个类访问同一对象 就像现在 我正在开发一个小型国际象棋游戏
  • Linux 中 Socket 的发送缓冲区为空?

    有没有办法检查 TCP 连接的发送缓冲区是否完全为空 到目前为止我还没有找到任何东西 只是想确保在仍有数据传输到某个客户端时我的服务器没有关闭连接 我正在使用轮询来检查是否能够在非阻塞套接字上发送数据 但这样我就无法知道是否所有内容都已发送
  • CSS多行省略号跨浏览器

    我的网页中有一个具有固定宽度和高度的 div 以下 css 仅适用于单行文本 overflow hidden text overflow ellipsis white space nowrap 如何使用具有跨浏览器兼容性的纯 css 在该
  • 如何检查是否授予“android.permission.PACKAGE_USAGE_STATS”权限?

    背景 我正在尝试获取应用程序启动的统计信息 在 Lollipop 上可以使用使用情况统计管理器类 本身 原帖here 显现
  • 如何在一般github的markdown中显示数学方程(不是github的博客)

    经过调查 我发现 mathjax 可以做到这一点 但是当我在 markdown 文件中编写一些示例时 它没有显示正确的方程 我已将其添加到 markdown 文件的头部 并输入 mathjax 语句 E mc 2 x 1 2 frac b
  • 如何使谷歌地图中的标记图像闪烁

    我在地图上有一些标记 代码部分在这里 var icons media green png media red png media blue png media yellow png var marker new google maps Ma
  • 折线的距离

    我正在折线中工作 我需要获得它的距离 因此 如果有人可以提供帮助 我将非常感激 此致 这是我的代码 function polyline downloadUrl xmlPolyline asp function data var xml xm
  • javafx fxml 组合框错误

    我试图将字符串添加到 javafx 组合框 但我不断收到上述错误 no suitable method found for add String method Collection add CAP 1 is not applicable a
  • Java 是否保证 Object.getClass() == Object.getClass()?

    我在这里确实指的是身份平等 例如 以下内容是否总是打印true System out println foo getClass fum getClass 是的 类标记是唯一的 对于任何给定的类加载器来说 IE 您将始终获得对同一物理对象的引
  • Android 应用程序 - 尝试在空对象引用上调用接口方法“int java.util.List.size()”

    我正在创建一个在网格视图中显示电影海报的应用程序 我正在使用 themoviedb org 的 API 问题是当我运行我的应用程序时出现以下错误 并且我正在努力修复它 07 18 20 27 39 244 2751 2751 E Andro
  • 如何在 swift 中使用 Gmail api 发送电子邮件

    The 邮箱API没有关于如何执行此操作的明确文档 我一直在尝试this但空气中有很多东西 我已经寻找过这样的外部资源 Source 1 and Source 2 第一个似乎利用了api的潜力 使用了函数queryForUsersMessa
  • jQuery 无法与我的 Blazor 应用程序正常工作

    我有以下脚本 它在从浏览器启动的简单 html 文件中运行良好 scroll to click event gt whatever here 但是 当将其与 Blazor 一起使用时 单击我的按钮时不会触发它 我找到了一个解决方法 即将第一
  • 如何订阅通过@angular/cdk/portal注入的组件的Observable?

    我正在尝试实现一个基本的 非常基本的 模式实现 我有一个ModalService and a ModalComponent The ModalService创建一个实例ModalComponent并使用 angular cdk portal