我有一个带有事件的组件,如下所示:
<menu-elem (onClick)="reallyCoolEvent($event)"></custom-component>
现在,我可以使用reallyCoolEvent
中的EventEmitter触发我的custom-component
。
@Output() onClick= new EventEmitter();
this.onClick.emit(stuff);
像这样,在我的其他组件中,将调用函数reallyCoolEvent
,并将stuff
传递给该函数。这非常有效!
现在,让我们说,我想出于任何原因复制该组件,我想从原始事件中触发相同的事件。现在,我正在浏览我的onClick
列表,如果它们符合我的标准,我会将它们存储在我在页面上其他位置显示的列表中。当我从那里触发onClick
时,事件永远不会被触发。
<menu>
<menu-elem label="Action 1" (onClick)="superCoolEvent($event)"></menu-elem>
<menu-elem label="Action 2" (onClick)="superCoolEvent2($event)"></menu-elem>
<menu-elem label="Action 3" (onClick)="superCoolEvent3($event)"></menu-elem>
</menu>
在menu
:
模板:
<div>
<ng-content></ng-content>
</div>
<sub-menu *ngFor="let subMenu of subMenus" [style.top]="subMenu.top" [style.left]="subMenu.left" [items]="subMenu.items"></sub-menu>
在sub-menu
:
模板:
<menu-elem *ngFor="let item of items" [label]="item.label"></menu-elem>
通过这样做,我希望能够触发onClick
中的<div class="here">
并仍然从原始模板触发事件:reallyCoolEvent($event)
。我不知道我是否可以这样做。当然onClick
未设置,因为我不再拥有模板中的数据。或者至少,我不知道如何获取数据。
我到目前为止唯一的解决方案是复制我的条目:
<menu>
<menu-elem label="1" (onClick)="superCoolEvent($event)"></menu-elem>
<menu-elem label="2" (onClick)="superCoolEvent2($event)"></menu-elem>
<menu-elem label="3" (onClick)="superCoolEvent3($event)"></menu-elem>
<div class="test">
<menu-elem label="1" (onClick)="superCoolEvent($event)"></menu-elem>
<menu-elem label="2" (onClick)="superCoolEvent2($event)"></menu-elem>
<menu-elem label="3" (onClick)="superCoolEvent3($event)"></menu-elem>
</div>
</menu>
根据我的标准,我可以显示或不显示,但我不喜欢这种方式,因为模板变得太大而没有。
答案 0 :(得分:1)
您的基本问题是自定义事件不会在Angular中冒泡。
由于您的menu
看起来像这样:
<div>
<ng-content></ng-content>
</div>
<sub-menu *ngFor="let subMenu of subMenus" [items]="subMenu.items"></sub-menu>
上述模板中sub-menu
内触发的任何事件都不会在sub-menu
之外自动提供。
因此,如果您希望customEvent
模板中的sub-menu
在sub-menu
之外可用,则必须手动传播该事件。类似的东西:
<div>
<ng-content></ng-content>
</div>
<div class="here">
<sub-menu *ngFor="let item of items" label="item.label" (submenuCustomEvent)="menuCustomEvent.emit($event)"></sub-menu>
</div>
其中submenuCustomEvent
是EventEmitter
的{{1}}属性,而sub-menu
属性为menuCustomEvent
的{{1}}。
修改强>
这意味着您的EventEmitter
必须看起来像:
menu
,您的sub-menu
变为:
@Component({
.....
template: `
<menu-elem *ngFor="let item of items"
[label]="item.label"
(customEvent)="submenuCustomEvent.emit($event)
>
</menu-elem>
`
})
export class Submenu {
.....
@Output()
submenuCustomEvent = new EventEmitter();
....
}
因此,您现在使用menu
的模板如下所示:
@Component({
.....
template: `
<div>
<ng-content></ng-content>
</div>
<sub-menu *ngFor="let subMenu of subMenus"
[items]="subMenu.items"
(submenuCustomEvent)="menuCustomEvent.emit($event)"
>
</sub-menu>
`
})
export class Menu {
.....
@Output()
menuCustomEvent = new EventEmitter();
....
}
注意事项:
如果您需要区分menu
嵌套在<menu (menuCustomEvent)="superCoolEvent($event)">
<menu-elem label="Action 1" (customEvent)="superCoolEvent($event)"></menu-elem>
<menu-elem label="Action 2" (customEvent)="superCoolEvent2($event)"></menu-elem>
<menu-elem label="Action 3" (customEvent)="superCoolEvent3($event)"></menu-elem>
</menu>
内的menu-elem
事件,您可能需要在sub-menu
发出的事件中添加一些其他信息。
我在示例中为submenuCustomEvent
和menu
命名了事件发射器以突出显示差异,但您可以在代码中使用相同的事件发射器名称(即调用所有嵌套事件发射器sub-menu
)
在此方案中,服务可能有助于避免通过组件层次结构手动连接事件发射器。如果点击onClick
内的menu
而没有中间事件传播
menu-elem
的顶级组件/ LI>
最后,您使用的是自定义sub-menu
事件。但是,如果直接使用浏览器onClick
事件,则可以避免手动传播,因为浏览器click
事件会传播。但是,您无法控制所发出事件的形状,因此存在此限制。
答案 1 :(得分:0)
我不确定我是否完全了解你。但是,您可以将子组件的引用注入子组件并使用父组件的偶数组。
constructor(private myParent: Parent) {}
go() {
this.myParent.custometEvent.emit(data);
}