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

时间:2015-11-04 19:47:28

标签: angular observable eventemitter

根据我的理解,.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);
    });
  }
}

在这个plnkr(http://plnkr.co/edit/rNdInA?p=preview)中,你从一个evt对象及其发射器函数(源自注入组件构造函数的Service)调用.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(...)function invokation?

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

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

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

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

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

我对你的上一个问题感到有些困惑但是想到了这个词,并且收到了一条消息。&#34;你必须倾听才能实现订阅方法的功能。

现在你可以调用那个可观察的东西(即使在其他服务中),IMO是组件之间通信的最佳方式。如果其他组件存在或正在倾听,他们不需要知道他们在树中的位置或小心。

我以我的方式工作HERE (仍在Alpha45上)

RxJs source and info on subject

Angular2 source and info on the subject inside the eventEmitter

答案 1 :(得分:5)

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

var evtEmitter = new EventEmitter();

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