在Angular

时间:2017-08-22 21:20:30

标签: angular observer-pattern eventemitter

我正在尝试使用Angular中的EventEmitter实现Observer类型的模式。

例如,我有一个名为 component1Publisher

的发布商
component1Publisher: EventEmitter<any> = new EventEmitter();

发布如下事件

this.component1Publisher.emit(data);

订阅多个组件,如下所示

component1Publisher.subscribe((data:any) => {
            //do something here;

          });

您可以看到发布者是静态声明的。在我的项目中,发布者和子网站是完全动态的。所以我想根据我的唯一组件名称创建这个EventEmitter实例和订阅者。如下所示

createEvent(uniqueName:string){
//new unique eventEmitter
}

我的问题        我有一个可重用的框架来创建一个用户可以带来框架本身提供的小部件的仪表板。所以我试图在小部件之间进行通信以使其具有交互性。例如,当您单击小部件时应通知所有其他小部件。为此,我计划告诉用户提供动态服务。在动态服务中有一些像onWidgetClick()的方法,它将通过动态解析服务来通过框架触发。在该方法中,用户可以创建要发布的事件。它将通过新数据通知所有小部件,框架将使用新数据更新它(所有可重用的小部件都有订阅者)。

你能否帮我解决这个问题,或建议有没有办法做这种实施

2 个答案:

答案 0 :(得分:1)

根据您最终要完成的工作,可能不需要这样做。您可以利用Angular的更改检测来提供所需的通知。

例如,您可以设置如下服务:

import { Injectable } from '@angular/core';

@Injectable() 
export class DataService {
  serviceData: string; 
}

任何绑定到该数据的模板都会自动通知更改(无需任何事件)。

我在这里有一篇博文:https://blogs.msmvps.com/deborahk/build-a-simple-angular-service-to-share-data/

这里有一个吸烟者:https://plnkr.co/edit/KT4JLmpcwGBM2xdZQeI9?p=preview

答案 1 :(得分:1)

我会在任何组件/指令中定义一张地图(我认为这是正确的术语?)&#39;这个&#39;是指。类似的东西:

componentPublishers: { [index:string] : EventEmitter<any> } = {};

该代码只是说,我创建了一个包含EventEmitters的对象,所有这些都由字符串标识(您可以使用字符串或数字作为标识符,但几乎在所有情况下人们都使用字符串)。

然后,您可以使用括号表示法(在JS中用于向对象添加新属性),使用您喜欢的任何名称向其添加EventEmitters。

createEvent(uniqueName:string){
  this.componentPublishers[uniqueName] = new EventEmitter<any>();

 // and maybe you'd want to return it?

  return this.componentPublishers[uniqueName];
}

创建之后,您应该可以像平时一样访问它而不使用括号表示法。通过使用上面显示的地图,typescript将知道componentPublishers对象的任何属性都将是一个事件发射器。

this.componentPublishers.myNewEventEmitter.emit('some value');

注意:如果您尝试使用括号表示法向对象添加属性,如果您不首先对其进行实例化,则会出现错误。我只是将它实例化为一个空对象。

 ... =  {};

所以一定要这样做。

你也可以创建一个事件发射器阵列并将新的发射器推入其中,但是这很快就会变得笨拙你必须跟踪索引。通过使用地图,您可以像常规对象一样按名称访问它们,并且仍然可以使用Typescript的静态类型检查。