Angular 2将事件从父级发送给所有子级

时间:2017-02-03 09:50:27

标签: angular

我试图实现一个简单的菜单栏。我有一个主菜单栏组件和许多可以具有不同深度的子菜单。我想在关闭主菜单栏时关闭每个子菜单。所以我希望父组件向每个孩子发送一个没有任何数据的简单事件。

我想这样做而不必在使用子菜单组件时声明任何输入,因为此事件订阅是强制性的,并且对于每个子菜单都是相同的。因此,宣言将更加简单,并将避免进一步的错误。

换句话说,我在菜单栏组件中有这个:

<sub-menu [title]="File">
    <sub-menu [title]="New" (onclick)="newFile()"></sub-menu>
    <sub-menu [title]="Open" (onclick)="openFile()"></sub-menu>
    <sub-menu [title]="Save" (onclick)="saveFile()"></sub-menu>
</sub-menu>
<sub-menu [title]="Edit">
    <sub-menu [title]="Copy" (onclick)="copy()"></sub-menu>
    <sub-menu [title]="Paste" (onclick)="paste()"></sub-menu>
</sub-menu>

并希望此父组件将事件发送到每个子菜单,而不必声明如下所示:

<sub-menu [title]="File" [mainClosed]="closed">
    <sub-menu [title]="New" (onclick)="newFile()" [mainClosed]="closed"></sub-menu>
    <sub-menu [title]="Open" (onclick)="openFile()" [mainClosed]="closed"></sub-menu>
    <sub-menu [title]="Save" (onclick)="saveFile()" [mainClosed]="closed"></sub-menu>
</sub-menu>
<sub-menu [title]="Edit" [mainClosed]="closed">
    <sub-menu [title]="Copy" (onclick)="copy()" [mainClosed]="closed"></sub-menu>
    <sub-menu [title]="Paste" (onclick)="paste()" [mainClosed]="closed"></sub-menu>
</sub-menu>

2 个答案:

答案 0 :(得分:3)

您可以使用add(Component)将子组件作为ViewChildren

注入父组件

在您的父组件中,您需要定义类似于此

的内容
@ViewChildren

其中import { ViewChildren, QueryList } from '@angular/core'; export class parentMenuComponent { @ViewChildren(SubMenu) allSubMenus: QueryList<SubMenu>; ... constructor() { } closeAll(){ this.allSubMenus.forEach((subMenu) => subMenu.close()); } } 是子组件的名称

有关SubMenu&amp;可以找到@ViewChild

的工作@ViewChildren

答案 1 :(得分:1)

@Injectable() 
class MenuShared {
  private subject = new BehaviorSubject(null);
  readonly close:Observable = this.subject.asObservable();

  notifyClose() {
    this.subject.next(true);
  }
}
    
@Component({
  selector: 'sub-menu',
  providers: [MenuShared]
})
export class SubMenuComponent {
  constructor(
      private menuShared:MenuShared, 
      @SkipSelf() @Optional() private parentMenuShared:MenuShared) {
    parentMenuShared.close.subscribe((_) => {
      this.closed = true;
      this.onClose();
  }
  onClose() {
    this.menuShared.notifyClose();
  }
}

这样,每个菜单都可以与自己及其子女共享服务实例。它可以订阅父通知以关闭自己,并通知孩子自己被关闭。

@SkipSelf()是要从自身获取实例。 @Optional()不会在根菜单上出现错误,该菜单无法从父进程注入。