孩子在Angular 2中听父母事件

Ham*_*edi 67 javascript rxjs eventemitter typescript angular

在有角度的文档中,有一个关于从父母那里听儿童事件的话题.没关系.但我的目的是反向的!在我的应用程序中有一个'admin.component',它包含管理页面的布局视图(侧边栏菜单,任务栏,状态等...).在这个父组件中,我配置了路由器系统,用于更改管理员其他页面之间的主视图.问题是在更改后保存内容,用户单击任务栏中的保存按钮(位于admin.component中),子组件必须侦听该click事件以执行保存人员.

Ste*_*aul 108

为了后人,我想我会提到更常规的解决方案:只需获取对ViewChild的引用,然后直接调用其中一个方法.

@Component({
  selector: 'app-child'
})
export class ChildComponent {

  notifyMe() {
    console.log('Event Fired');
  }
}

@Component({
  selector: 'app-parent',
  template: `<app-child #child></app-child>`
})
export class ParentComponent {

  @ViewChild('child')
  private child: ChildComponent;

  ngOnInit() {
    this.child.notifyMe();
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 一旦输入父组件,它就会崩溃...“无法读取未定义的属性'notifyMe'。 (2认同)
  • @BernoulliIT你提出了一个很好的观点.我想在一天结束时他们完成了大致相同的事情.我的解决方案使用更少的代 他的解决方案意味着父组件不必注入子组件来发送消息.RXJS很棒,但我经常在Angular项目中看到过度使用它.人们认为这是"银弹"或其他东西.它实际上可以使事情变得比它们需要的复杂得多.看看他在`ngOnDestroy()`方法中的注释.就我而言,这太模糊了.这只是一个等待恕我直言的错误. (2认同)

Thi*_*ier 88

我认为这个文档可能对您有所帮助:

实际上,您可以利用父级为其子级提供的可观察/主题.像这样的东西:

@Component({
  (...)
  template: `
    <child [parentSubject]="parentSubject"></child>
  `,
  directives: [ ChildComponent ]
})
export class ParentComponent {
  parentSubject:Subject<any> = new Subject();

  notifyChildren() {
    this.parentSubject.next('some value');
  }
}
Run Code Online (Sandbox Code Playgroud)

子组件可以简单地订阅此主题:

@Component({
  (...)
})
export class ChildComponent {
  @Input()
  parentSubject:Subject<any>;

  ngOnInit() {
    this.parentSubject.subscribe(event => {
      // called when the notifyChildren method is
      // called in the parent component
    });
  }

  ngOnDestroy() {
    // needed if child gets re-created (eg on some model changes)
    // note that subsequent subscriptions on the same subject will fail
    // so the parent has to re-create parentSubject on changes
    this.parentSubject.unsubscribe();
  }

}
Run Code Online (Sandbox Code Playgroud)

否则,您可以以类似的方式利用包含此类主题的共享服务...

  • 使用此方法比ViewChild有什么优势吗? (4认同)

cha*_*rsi 10

如果我正确理解了这个问题,那么这里可能会采用更简单的方法.假设 -

  • OP在父组件中有一个保存按钮
  • 需要保存的数据位于子组件中
  • 可以从服务访问子组件可能需要的所有其他数据

在父组件中

<button type="button" (click)="prop1=!prop1">Save Button</button>
<app-child-component [setProp]='prop1'></app-child-component>
Run Code Online (Sandbox Code Playgroud)

在孩子..

prop1:boolean;
  @Input()
  set setProp(p: boolean) {
    // -- perform save function here
}
Run Code Online (Sandbox Code Playgroud)

这只是将按钮单击发送到子组件.子组件可以从那里独立保存数据.

编辑:如果父模板中的数据也需要与按钮单击一起传递,这也可以通过这种方法实现.如果是这种情况,请告诉我,我将更新代码示例.