Angular 2 EventEmitter - 从服务函数广播 next( ... )

Angular 2 EventEmitter - Broadcasting next( ... ) from a Service function

据我了解,.toRx().subscribe( ...) 函数用于接收消息,而 .next() 函数用于广播消息

在此 plnkr ( http://plnkr.co/edit/MT3xOB?p=info ) 中,您从一个数据对象调用 .toRx().subscribe( ... ) 函数,该数据对象似乎 defined/derived 最初来自模板:

@Component({
  selector : 'child-cmp',
  template : '',
  inputs : ['data']
})
class ChildCmp {
  afterViewInit() {
    this.data.toRx().subscribe((data) => {
      console.log('New data has arrived!', data);
    });
  }
}

在此 plnkr ( http://plnkr.co/edit/rNdInA?p=preview ) 中,您从 evt 对象及其发射器函数调用 .toRx().subscribe( ... ) 函数(源自注入到组件构造函数中的服务)

@Component({
  selector : 'parent-cmp',
  template : ''
})
class ParentCmp {
  constructor(evt: EventService) {
    evt.emitter.subscribe((data) => 
      console.log("I'm the parent cmp and I got this data", data));
  }
}

BROADCAST 是否有可能在服务本身的函数中发生,同时,组件是否有可能在不依赖返回的服务对象或模板数据对象链接的情况下接收消息它的 .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();
    }
}

更新到 2.0 稳定版: EventEmitter 现在仅用于组件通信。这是 Subjects 和 ReplaySubjects 的更好用途。我已将示例更新为 2.0 代码。

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

所以现在 (Alpha 45) eventEmitter 有 toRx() 方法,returns 一个 RxJS SUBJECT

你可以 google 稍微了解一下那是什么以及你可以用它做什么,但这才是你真正在搞乱的东西。当您调用 toRx() 时,它只是 returns 来自 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);
  }
}

然后在您的组件中订阅发射器

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));
    }
  }
}

这是一个扩展的 class,带有内置的取消订阅(处理)

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();
  }
}

我对你的最后一个问题有点困惑,但想想这个术语 "receive a message." 你必须 一些东西,这就是订阅方法的作用,并且是必须的。

很酷的是,现在您可以在任何地方(甚至在其他服务中)调用该 observable,而 IMO 是组件之间通信的最佳方式。他们不需要知道自己在树中的位置,也不需要关心其他组件是否存在或正在监听。

我用我的工作方式分叉了你的 Plunker HERE (仍在 Alpha45 上)

RxJs source and info on subject

Angular2 source and info on the subject inside the eventEmitter

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

var evtEmitter = new EventEmitter();

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