Angular 角度2事件发射器-从服务函数广播下一个(…)

Angular 角度2事件发射器-从服务函数广播下一个(…),angular,observable,eventemitter,Angular,Observable,Eventemitter,据我所知,.toRx().subscribe(…)函数用于接收消息,.next()函数用于广播消息 在这个plnkr()中,您可以从一个数据对象调用.toRx().subscribe(…)函数,该数据对象似乎最初是从模板定义/派生的: @Component({ selector : 'child-cmp', template : '', inputs : ['data'] }) class ChildCmp { afterViewInit() { this.data.to

据我所知,.toRx().subscribe(…)函数用于接收消息,.next()函数用于广播消息

在这个plnkr()中,您可以从一个数据对象调用.toRx().subscribe(…)函数,该数据对象似乎最初是从模板定义/派生的:

@Component({
  selector : 'child-cmp',
  template : '',
  inputs : ['data']
})
class ChildCmp {
  afterViewInit() {
    this.data.toRx().subscribe((data) => {
      console.log('New data has arrived!', data);
    });
  }
}
在这个plnkr()中,您从evt对象及其发射器函数(源自注入组件构造函数的服务)调用.toRx().subscribe(…)函数

广播是否可以在服务本身的函数中进行,同时,组件是否可以在不依赖返回的服务对象或模板数据对象来链接其.toRX().subscribe(…)函数调用的情况下接收消息

import {Injectable, EventEmitter} from 'angular2/angular2';
@Injectable()
export class DataService {
    items:Array<any>;
    dispatcher: EventEmitter = new EventEmitter();
    constructor() {
        this.items = [
            { name: 'AAAA' },
            { name: 'BBBB' },
            { name: 'CCCC' }
        ];
    }
    getItems() {
        return this.items;
    }
    sendItems() {
        this.dispatcher.next( this.items );
    } 
}
export var DATA_BINDINGS: Array<any> = [
    DataService
];


@Component({
    selector: 'rabble'
})
@View({
    ...
})
export class Rabble {

    items       : Array<any>;

    constructor( public dataService  : DataService) { 

        console.log('this.routeParam', this.dataService.getItems());
    }

    afterViewInit() {
        this.???.toRx().subscribe((data) => {
            console.log('New item data has arrived!', data);
        });
    }

    handleClick() {
        this.dataService.sendItems();
    }
}
从'angular2/angular2'导入{Injectable,EventEmitter};
@可注射()
导出类数据服务{
项目:阵列;
dispatcher:EventEmitter=新的EventEmitter();
构造函数(){
此项。项目=[
{name:'AAAA'},
{name:'BBBB'},
{name:'CCCC'}
];
}
getItems(){
归还此物品;
}
sendItems(){
this.dispatcher.next(this.items);
} 
}
导出变量数据\u绑定:数组=[
数据服务
];
@组成部分({
选择器:“乌合之众”
})
@看法({
...
})
出口阶级乌合之众{
项目:阵列;
构造函数(公共数据服务:数据服务){
log('this.routeParam',this.dataService.getItems());
}
afterViewInit(){
此.??.toRx().订阅((数据)=>{
log('新项目数据已到达!',数据);
});
}
handleClick(){
this.dataService.sendItems();
}
}

更新为2.0稳定版:EventEmitter现在仅用于组件通信。这对于主题和重放主题有更好的用途。我已经将示例代码更新为2.0代码

更新到BETA 1:您不再需要在发射器上调用.toRx(),因此我正在更新代码以匹配,并添加了一个取消订阅的示例

现在(Alpha 45)eventEmitter有一个toRx()方法,它返回一个RxJSSUBJECT

你可以在谷歌上搜索一下这是什么,你可以用它做什么,但这是你真正在搞乱的东西。调用toRx()时,它只从eventEmitter返回内部主题,因此您可以在服务构造函数中执行此操作

然后,我将您想要进行广播的功能添加到事件服务中

class EventService {
  //could be regular Subject but I like how ReplaySubject will send the last item when a new subscriber joins
  emitter: ReplaySubject<any> = new ReplaySubject(1);
  constructor() {

  }
  doSomething(data){
    this.emitter.next(data);
  }
}
这是一个扩展类,内置了一个unsubscribe(dispose)

我对你的最后一个问题有点困惑,但想想“接收消息”这个词。你必须倾听一些东西,这就是subscribe方法的作用和要求

很酷的事情是,现在你可以称之为随处可见(甚至在其他服务中),IMO是组件之间通信的最佳方式。他们不需要知道自己在树中的位置,也不需要关心其他组件是否存在或正在侦听

我用我的工作方式叉了你的东西 (仍在Alpha45上)


在Beta版中,您不再需要通过toRx()将其转换为RxJs对象


丹尼斯先生。我仍然对一些相关的/挥之不去的功能感到好奇。在angular 1$Broadcast和$on中,订阅特定“频道”时使用的正确EventEmitter语法是什么?为了实现一个“通道”,我只创建了第二个新的EventEmitter变量,或者只创建了一个绑定到现有的_emitter变量?…=这个$scope.$broadcast('myCustomEvent',{someProp:'Sending you an Object!'//send any you want})$作用域.$on('myCustomEvent',函数(事件,数据){console.log(数据);//'要发送的数据'});老实说,在我的使用中,我跳过EventEmitter,直接创建一个新的可观察对象(现在整个.toRx()东西都很痛苦),然后将它放在一个保持对象中。我觉得EventEmitter更适合组件与服务之间的通信。(IMO)您可能希望为每个“通道”创建一个新的通道,否则每次更新流时都需要过滤逻辑。然后我只需要调用:
myobserver.observators.myCustomEvent.subscribe(…)
,或者你可以在你的服务中做一个助手,比如:
myobserver.listen('myCustomEvent',(data)=>{},(error)=>{})
我周末在想这个问题,但是我错过了你想要的一个要点。对于计划的发布/订阅性质,您确实应该使用EventEmitter。通过这种方式,您可以轻松地从其他函数执行.next()。这是一个很好的解决方案,但您忘记了取消订阅事件处理程序。如果您不取消订阅,那么如果您有该组件的多个实例,则会多次调用该处理程序。我找到了一个“unsubscribe”方法,但它不能像预期的那样工作。只有当您需要一个响应时,如果是这种情况,您可以在调用者内部调用complete()。从外观上看,您可以使用dispose()(RxJS主题),但我从未测试过。。。
class EventService {
  //could be regular Subject but I like how ReplaySubject will send the last item when a new subscriber joins
  emitter: ReplaySubject<any> = new ReplaySubject(1);
  constructor() {

  }
  doSomething(data){
    this.emitter.next(data);
  }
}
class ParentCmp {
  myData: any;
  constructor(private evt: EventService) {
    //rx emitter
    this.evt.emitter.subscribe((data) => {
      this.myData = data;
      console.log("I'm the parent cmp and I got this data", data));
    }
  }
}
export class ParentCmp implements OnDestroy {
  myData: any;
  subscription: any;
  constructor(evt: EventService) {
    //rx emitter
    this.subscription = evt.emitter.subscribe((data) => {
      this.myData = data;
      console.log("I'm the parent cmp and I got this data", data));
    }
  }
  ngOnDestroy() {
    this.subscription.dispose();
  }
}
var evtEmitter = new EventEmitter();

evtEmitter.emit(args);
evtEmitter.subscribe((args)=>{console.log('new event')});