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

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

问题描述

我想实现常见的 Angular 1.x 模式,即在 Angular 2 的父指令中包含子指令.这是我想要的结构.

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

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

这是我的 Foo 到目前为止:

@Component({选择器:'foo',模板:`<div><ng-content></ng-content>

`})出口类 Foo {@ContentChildren(Bar) 项目:QueryList;}

这是我的Bar:

@Component({选择器:'酒吧',模板:`<div (click)="clickity()"><ng-content></ng-content>

`})导出类 Bar {点击率(){console.log('请把这个广播给父母!');}}

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

解决方案

另一个答案在解决问题方面做得很差.EventEmitters 仅用于与 @Outputs 结合使用,并且这个问题没有利用 Angular 2 内置的依赖注入或 RxJS 的特性.

具体来说,如果不使用 DI,您会强迫自己进入一个场景,如果您重用依赖于静态类的组件,它们都将收到相同的事件,而您可能不想要这种情况.

请看下面的例子,利用DI,很容易多次提供同一个类,使用起来更加灵活,同时也避免了有趣的命名方案的需要.如果您需要多个事件,您可以使用不透明标记提供这个简单类的多个版本.

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

//服务导入 'rxjs/Rx';从 'rxjs/Rx' 导入 {Subject,Subscription};导出类 EmitterService {私人活动 = 新主题();订阅(下一个,错误,完成):订阅者{返回 this.events.subscribe(next,error,complete);}下一个(事件){this.events.next(事件);}}@成分({选择器:'酒吧',模板:`<button (click)="clickity()">点击我</button>`})导出类 Bar {构造函数(私有发射器:EmitterService){}点击率(){this.emitter.next('请把这个广播给父母!');}}@成分({选择器:'foo',模板:`<div [ngStyle]="styl"><ng-content></ng-content>

`,提供者:[EmitterService],指令:[酒吧]})出口类 Foo {风格 = {};私人订阅;构造函数(私人发射器:EmitterService){this.subscription = this.emitter.subscribe(msg => {this.styl = (this.styl.background == 'green') ?{'背景':'橙色'}:{'背景':'绿色'};});}//通过销毁内存来确保我们没有内存泄漏//当我们的组件被销毁时订阅ngOnDestroy() {this.subscription.unsubscribe();}}

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>

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

Here's my Foo so far:

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

And here's my 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!');
  }
}

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

解决方案

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.

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.

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.

Working Example: 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天全站免登陆