Angular 2 EventEmitter-从Service函数广播next(...) [英] Angular 2 EventEmitter - Broadcasting next( ... ) from a Service function

查看:250
本文介绍了Angular 2 EventEmitter-从Service函数广播next(...)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

To my understanding, the .toRx().subscribe( ... ) function is meant to RECEIVE messages and the .next() function is meant to BROADCAST messages

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

In this plnkr ( http://plnkr.co/edit/MT3xOB?p=info ) , you invoke the .toRx().subscribe( ... ) function from a data object that seems to be defined/derived originally from the template:

@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(...)函数

In this plnkr ( http://plnkr.co/edit/rNdInA?p=preview ) , you invoke the .toRx().subscribe( ... ) function from an evt object and its emitter function (originating from Service injected into the component's constructor)

@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可能在Service本身的功能中发生,而与此同时,Component是否有可能在不依赖返回的Service对象或Template数据对象链接其消息的情况下接收消息. toRX().subscribe(...)函数调用?

Is is possible for the BROADCAST to take place in a function of the Service itself while at the same time, is it possible for the Component to RECEIVE the message without relying upon a returned Service object or Template data object to chain its .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稳定: EventEmitter现在仅用于组件通信.这对于Subject和ReplaySubjects是更好的用法.我已将示例更新为2.0代码.

UPDATED TO 2.0 Stable: EventEmitter is now solely for component communication. This is a better use for Subjects and ReplaySubjects. I've updated the examples to 2.0 code.

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

所以现在(Alpha 45) eventEmitter具有该toRx()方法,该方法返回RxJS SUBJECT

So right now (Alpha 45) The eventEmitter has that toRx() method which returns a RxJS SUBJECT

您可以在google上搜索一下它的含义以及可以使用的功能,但这实际上是您在搞弄的.调用toRx()时,它只是从eventEmitter返回内部主题,因此您可以在服务构造函数中完成此操作.

然后我将您要广播的功能添加到事件服务

Then I added the function you wanted to do the broadcast to the event service

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

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

Then in your component you subscribe to the emitter

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

这是带有内置unsubscribe(dispose)的扩展类

And here is a expanded class with a built in unsubscribe(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();
  }
}

对于您的最后一个问题,我有些困惑,但请考虑一下接收消息"一词.您必须收听某些内容,以便subscribe方法执行和需要执行此操作.

I'm a little confused about your last question but think of the term "receive a message." You have to be listening to something so thats what the subscribe method does and is required.

很酷的事情是,您现在可以在整个地方(甚至在其他服务中)也可以将其称为可观察的东西,而IMO是在组件之间进行通信的最佳方式.他们不需要知道它们在树中的位置,也不必关心其他组件是否存在或正在侦听.

Cool thing is now you can call that observable all over the place (even in other services) and IMO is the best way to communicate between components. They don't need to know their position in the tree or care if the other components exist or are listening.

我以工作方式分叉了您的柱塞这里 (仍在Alpha45上)

I Forked your Plunker with my way working HERE (still on Alpha45)

RxJ的主题来源和信息

查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆