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

Ben*_*ren 4 observable eventemitter angular

据我所知,.toRx().subscribe(...)函数用于接收消息,而.next()函数用于BROADCAST消息

在这个plnkr(http://plnkr.co/edit/MT3xOB?p=info)中,您从一个似乎最初定义/派生的数据对象中调用.toRx().subscribe(...)函数.模板:

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

在这个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));
  }
}
Run Code Online (Sandbox Code Playgroud)

是否可以在服务本身的功能中进行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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Den*_*lek 11

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

更新到BETA 1:您不再需要在发射器上调用.toRx(),因此我正在更新代码以匹配并向unSubscribe添加示例.

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

你可以谷歌搜索一下这是什么以及你可以用它做什么,但这是你实际上在搞乱的东西.当您调用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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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));
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这是一个扩展的类,内置取消订阅(配置)

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();
  }
}
Run Code Online (Sandbox Code Playgroud)

我对你的上一个问题感到有些困惑,但想到"接收消息"一词.你必须一些东西,以便订阅方法做什么和需要什么.

很酷的事情现在你可以在整个地方调用那个observable(即使在其他服务中),IMO是组件之间通信的最佳方式.他们不需要知道他们在树中的位置,也不需要关心其他组件是否存在或正在倾听.

我用我的方式在这里 工作(仍在Alpha45上)你的Plunker

RxJs主题的来源和信息

关于eventEmitter内主题的Angular2源和信息


tom*_*271 5

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

var evtEmitter = new EventEmitter();

evtEmitter.emit(args);
evtEmitter.subscribe((args)=>{console.log('new event')});
Run Code Online (Sandbox Code Playgroud)