子组件事件广播给父 [英] Child component events broadcast to parent

查看:75
本文介绍了子组件事件广播给父的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现在Angular 2的父指令中具有子指令的通用Angular 1.x模式.这是我想要的结构.

I'd like to implement the common Angular 1.x pattern of having child directives within a parent directive in Angular 2. Here's my desired structure.

<foo>
  <bar>A</bar>
  <bar>B</bar>
  <bar>C</bar>
</foo>

我希望这些Bar组件具有被发送到Foo组件的click事件.

I'd like for these Bar components to have click events that get emitted to the Foo component.

到目前为止,这是我的Foo:

Here's my Foo so far:

@Component({
  selector: 'foo',
  template: `
    <div>
      <ng-content></ng-content>
    </div>
  `
})
export class Foo {
   @ContentChildren(Bar) items: QueryList<Bar>;
}

这是我的Bar:

@Component({
  selector: 'Bar',
  template: `
    <div (click)="clickity()">
      <ng-content></ng-content>
    </div>
  `
})
export class Bar {
  clickity() {
    console.log('Broadcast this to the parent please!');
  }
}

当点击Foo之一时,如何通知Foo?

How do I go about notifying Foo whenever one of its Bars is clicked?

推荐答案

另一个答案在解决问题上做得很差. EventEmitters仅打算与@Outputs一起使用,并且此问题没有利用Angular 2内置的依赖项注入或RxJS的功能来实现.

The other answer does a very poor job of solving the problem. EventEmitters are only meant to be used in conjunction with @Outputs as well as this problem not taking advantage of the dependency injection built into Angular 2 or the features of RxJS.

具体来说,通过不使用DI,您将不得不陷入一种情况,即如果重用依赖于静态类的组件,它们将全部收到相同的事件,而这可能是您不希望的.

Specifically, by not using DI, you're forcing yourself into a scenario where if you reuse the components dependent on the static class they will all receive the same events, which you probably don't want.

请看下面的示例,利用DI可以轻松地多次提供相同的类,从而可以更灵活地使用,并且避免使用有趣的命名方案.如果您想要多个事件,则可以使用不透明标记提供此简单类的多个版本.

Please take a look at the example below, by taking advantage of DI, it is easy to provide the same class multiple times, enabling more flexible use, as well as avoiding the need for funny naming schemes. If you want multiple events, you could provide multiple versions of this simple class using opaque tokens.

工作示例: http://plnkr.co/edit/RBfa1GKeUdHtmzjFRBLm?p=preview

// The service
import 'rxjs/Rx';
import {Subject,Subscription} from 'rxjs/Rx';

export class EmitterService {
  private events = new Subject();
  subscribe (next,error,complete): Subscriber {
    return this.events.subscribe(next,error,complete);
  }
  next (event) {
    this.events.next(event);
  }
}

@Component({
  selector: 'bar',
  template: `
    <button (click)="clickity()">click me</button>
  `
})
export class Bar {
  constructor(private emitter: EmitterService) {}
  clickity() {
    this.emitter.next('Broadcast this to the parent please!');
  }
}

@Component({
  selector: 'foo',
  template: `
    <div [ngStyle]="styl">
      <ng-content></ng-content>
    </div>
  `,
  providers: [EmitterService],
  directives: [Bar]
})
export class Foo {
  styl = {};
  private subscription;
  constructor(private emitter: EmitterService) {
    this.subscription = this.emitter.subscribe(msg => {
      this.styl = (this.styl.background == 'green') ? {'background': 'orange'} : {'background': 'green'};
    });
  }
  // Makes sure we don't have a memory leak by destroying the
  // Subscription when our component is destroyed
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

这篇关于子组件事件广播给父的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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