Angular中没有等价的$scope.emit()或$scope.broadcast()吗?

我知道EventEmitter功能,但据我所知,它只会向父HTML元素发出一个事件。

如果我需要在fx和。还是DOM根组件和嵌套了几层的元素之间?


当前回答

不要使用EventEmitter来进行服务通信。

你应该使用Observable类型之一。我个人喜欢BehaviorSubject。

简单的例子:

你可以传递初始状态,这里我传递null

let subject = new BehaviorSubject(null);

当你想要更新主题时

next (myObject)科目。

观察任何服务或组件,并在其获得新的更新时采取行动。

subject.subscribe (this.YOURMETHOD);

这里有更多信息。

其他回答

我正在使用一个消息服务,包装rxjs主题(TypeScript)

Plunker示例:Message Service

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/filter'
import 'rxjs/add/operator/map'

interface Message {
  type: string;
  payload: any;
}

type MessageCallback = (payload: any) => void;

@Injectable()
export class MessageService {
  private handler = new Subject<Message>();

  broadcast(type: string, payload: any) {
    this.handler.next({ type, payload });
  }

  subscribe(type: string, callback: MessageCallback): Subscription {
    return this.handler
      .filter(message => message.type === type)
      .map(message => message.payload)
      .subscribe(callback);
  }
}

组件可以订阅和广播事件(发送方):

import { Component, OnDestroy } from '@angular/core'
import { MessageService } from './message.service'
import { Subscription } from 'rxjs/Subscription'

@Component({
  selector: 'sender',
  template: ...
})
export class SenderComponent implements OnDestroy {
  private subscription: Subscription;
  private messages = [];
  private messageNum = 0;
  private name = 'sender'

  constructor(private messageService: MessageService) {
    this.subscription = messageService.subscribe(this.name, (payload) => {
      this.messages.push(payload);
    });
  }

  send() {
    let payload = {
      text: `Message ${++this.messageNum}`,
      respondEvent: this.name
    }
    this.messageService.broadcast('receiver', payload);
  }

  clear() {
    this.messages = [];
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

(接收方)

import { Component, OnDestroy } from '@angular/core'
import { MessageService } from './message.service'
import { Subscription } from 'rxjs/Subscription'

@Component({
  selector: 'receiver',
  template: ...
})
export class ReceiverComponent implements OnDestroy {
  private subscription: Subscription;
  private messages = [];

  constructor(private messageService: MessageService) {
    this.subscription = messageService.subscribe('receiver', (payload) => {
      this.messages.push(payload);
    });
  }

  send(message: {text: string, respondEvent: string}) {
    this.messageService.broadcast(message.respondEvent, message.text);
  }

  clear() {
    this.messages = [];
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

MessageService的subscribe方法返回一个rxjs订阅对象,可以像这样取消订阅:

import { Subscription } from 'rxjs/Subscription';
...
export class SomeListener {
  subscription: Subscription;

  constructor(private messageService: MessageService) {
    this.subscription = messageService.subscribe('someMessage', (payload) => {
      console.log(payload);
      this.subscription.unsubscribe();
    });
  }
}

也可以看到这个答案:https://stackoverflow.com/a/36782616/1861779

Plunker示例:Message Service

我最喜欢的方法是在我的服务中使用行为主题或事件发射器(几乎相同)来控制我的所有子组件。

使用angular cli,运行ng gs来创建一个新的服务,然后使用BehaviorSubject或EventEmitter

export Class myService {
#all the stuff that must exist

myString: string[] = [];
contactChange : BehaviorSubject<string[]> = new BehaviorSubject(this.myString);

   getContacts(newContacts) {
     // get your data from a webservices & when you done simply next the value 
    this.contactChange.next(newContacts);
   }
}

当您这样做时,作为提供者使用您的服务的每个组件都将知道更改。只需订阅结果,就像你用eventEmitter;)

export Class myComp {
#all the stuff that exists like @Component + constructor using (private myService: myService)

this.myService.contactChange.subscribe((contacts) => {
     this.contactList += contacts; //run everytime next is called
  }
}

不要使用EventEmitter来进行服务通信。

你应该使用Observable类型之一。我个人喜欢BehaviorSubject。

简单的例子:

你可以传递初始状态,这里我传递null

let subject = new BehaviorSubject(null);

当你想要更新主题时

next (myObject)科目。

观察任何服务或组件,并在其获得新的更新时采取行动。

subject.subscribe (this.YOURMETHOD);

这里有更多信息。

您可以使用EventEmitter或可观察对象来创建向DI注册的事件总线服务。每个想要参与的组件只需将服务作为构造函数参数请求,并发出和/或订阅事件。

另请参阅

https://angular.io/docs/ts/latest/cookbook/component-communication.html !# bidirectional-service 委托:在Angular2中的EventEmitter或Observable

我们实现了一个ngModelChange可观察指令,它通过你在自己的组件中实例化的事件发射器发送所有模型更改。您只需将事件发射器绑定到该指令。

参见:https://github.com/atomicbits/angular2-modelchangeobservable

在html中,绑定你的事件发射器(本例中为countryChanged):

<input [(ngModel)]="country.name"
       [modelChangeObservable]="countryChanged" 
       placeholder="Country"
       name="country" id="country"></input>

在你的typescript组件中,对EventEmitter执行一些异步操作:

import ...
import {ModelChangeObservable} from './model-change-observable.directive'


@Component({
    selector: 'my-component',
    directives: [ModelChangeObservable],
    providers: [],
    templateUrl: 'my-component.html'
})

export class MyComponent {

    @Input()
    country: Country

    selectedCountries:Country[]
    countries:Country[] = <Country[]>[]
    countryChanged:EventEmitter<string> = new EventEmitter<string>()


    constructor() {

        this.countryChanged
            .filter((text:string) => text.length > 2)
            .debounceTime(300)
            .subscribe((countryName:string) => {
                let query = new RegExp(countryName, 'ig')
                this.selectedCountries = this.countries.filter((country:Country) => {
                    return query.test(country.name)
                })
            })
    }
}