【问题标题】:Listening to event broadcast by third party library in angular以角度收听第三方库广播的事件
【发布时间】:2019-02-21 04:11:20
【问题描述】:

我有一个第三方聊天库,我在 index.html 中导入为

<script type="text/javascript" src="/thirdPartyChatLibarary"></script>

这个库以聊天开始、聊天结束等形式广播事件。

我在广播的 AngularJs-v1.6 项目中捕获了相同的事件

scope.$on('cobrowse.linkClicked', callFunction());

我需要在我的 Angular-v7.0+ 项目中捕获相同的事件。

我知道 eventEmitter@input 属性,但它们会将孩子连接到父母,这里我有来自第三方的事件广播。

我不太确定来自rxjsObservable 是否有帮助。

是否有任何等效的角度 $on 可以全局捕获这些事件?

【问题讨论】:

  • 这个问题有点含糊,但总的来说,我建议不要全局导入,而是安装 npm 模块。然后,仅在需要它的组件中导入它。聊天库是否发布在 npm 上?
  • 不,它没有在 npm 上发布,我只是通过脚本标签使用它,我有两个项目,一个在 angularjs1.3 上工作,我可以在 $on 上获得它,而第二个在角js7.0。不可变的聊天库

标签: angular


【解决方案1】:

我想分享一些我尝试过的方法。

让我们首先讨论一下在我首先尝试过的应用程序中广播和监听事件的方法。

A) 应用程序内的事件广播接收

1) 使用@componethost 属性,例如

 @Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
  host: {
    "(document:click)": "onDocumentClicked($event)"
  }
})
export class AppComponent {
  onDocumentClicked(ev) {
    console.log("clicked", ev);
  }
}

2) 使用@HostListener

import { HostListener, Component } from "@angular/core";

添加函数和监听器

@HostListener("document:click", ["$event"])
  onDocumentClicked(ev) {
    console.log("clicked", ev);
  }

3) Observables 来自 rxjs

创建服务为

import { Injectable } from '@angular/core';
import { from, Subject } from 'rxjs';

@Injectable()
export class ListnerAndBroadcast {
    listeners: any;
    eventsSubject: any;
    events: any;

    constructor() {
        this.listeners = {};
        this.eventsSubject = new Subject();

        this.events = from(this.eventsSubject);

        this.events.subscribe(
            ({name, args}) => {
                if (this.listeners[name]) {
                    for (let listener of this.listeners[name]) {
                        listener(...args);
                    }
                }
            });
    }

    on(name, listener) {
        if (!this.listeners[name]) {
            this.listeners[name] = [];
        }

        this.listeners[name].push(listener);
    }

    off(name, listener) {
        this.listeners[name] = this.listeners[name].filter(x => x != listener);
    }

    broadcast(name, ...args) {
        this.eventsSubject.next({
            name,
            args
        });
    }
}

现在我们需要从任何子组件广播事件

this._ListnerAndBroadcast.broadcast('myCustomEvent', 'event');

就我而言,我从最深的组件页脚中广播了相同的内容。

并在根组件上接收它

this._ListnerAndBroadcast.on('myCustomEvent', (event) => {
      console.log('myCustomEvent received '+ event);
    }); 

我个人喜欢上述方法,因为它可以是动态的并且可以处理任何事件流。

B) 从第三方收到的或超出应用程序的事件

我用过Renderer2

作为

在子组件中添加为

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

renderer2.listen('document', 'myCustomEvent', (evt) => {
      console.log('getting it from renderer ', evt);
    })

现在我们需要广播事件。

为了模仿第三方事件服务,在浏览器控制台中运行以下代码

var event = new CustomEvent(
      'myCustomEvent',
      { detail: { 'param1': 1, 'param2': 2 } }
    );
    document.dispatchEvent(event);

您将能够在控制台中看到结果。

我正在使用 Angular 7+ 和 rxjs 6.2

链接帮助我学习刚刚整合了上述所有解决方案

Global Events and Event Delegation

Global event listener with observable

谢谢!

【讨论】:

    【解决方案2】:

    你可以使用 RxJS 提供的fromEvent 操作符。 Check out an example here. 这个操作符非常不言自明!它从一个事件中创建一个 Observable。

    【讨论】:

      猜你喜欢
      • 2023-02-09
      • 2014-09-06
      • 2019-01-15
      • 1970-01-01
      • 2016-05-04
      • 1970-01-01
      • 2012-06-01
      • 2018-01-08
      • 2023-03-04
      相关资源
      最近更新 更多