【问题标题】:How to listen to events inside the child component dispatched by the parent component如何监听父组件调度的子组件内部的事件
【发布时间】:2026-02-14 17:10:01
【问题描述】:

当一个事件被一个组件分派时,事件流的三个阶段,捕获 - 事件从应用程序流向分派事件的组件,当事件到达实际分派事件的目标时,目标,然后是事件从目标流向应用程序的冒泡阶段。有一种情况,Application 有子 comp1,comp1 有子 comp2。我在 comp1 中有一个按钮,用于调度事件,我想在 comp2 中收听该事件。理想情况下,事件将从 Application->comp1->button->comp1->Application 流出。我怎样才能实现我的目标?

【问题讨论】:

    标签: apache-flex events


    【解决方案1】:

    comp1 内部调度您的事件并确保它冒泡:

    myButton.addEventListener(MouseEvent.CLICK, handleMyButtonClick);
    
    private function handleMyButtonClick(event:MouseEvent):void {
         dispatchEvent(new Event("myCustomEvent", true));
    }
    

    现在在comp2 内,在stage 上监听此事件:

    stage.addEventListener("myCustomEvent", handleMyCustomEvent);
    

    就是这样:因为事件冒泡,它会总是在某个时候点击stage。因此,您可以使用它在任何地方收听。只是不要忘记在尝试附加侦听器之前确保设置了comp2stage 属性。

    注意:请注意,您应用程序中的所有组件都将能够看到此事件,因此请确保正确的组件处理正确的事件。对于初学者,我永远不会在内置事件中使用这种方法;仅使用 types 与内置事件不一致的自定义事件。

    【讨论】:

    • 如果其他东西调度了相同的事件,comp1 也会听到。
    【解决方案2】:

    您的建议可能不是最好的方法。您可能应该通过让父母明确地做一些帮助孩子知道该做什么的事情来更好地处理这个问题。

    一种方法是使用事件总线的概念,例如what you see in RobotLegs。只需给您的 child2 一个名为 eventBus 的公共字段或属性,其类型为 IEventDispatcher。然后,您可以让父级使用this 填充此属性。我一般把这样的属性设置成getter/setter,这样当child从stage中移除时该属性可以为null,child可以remove its listeners

    这使您可以从实现这一目标所需的确切内容开始,但如果您发现自己在需要它来监听不同对象的情况下使用 child2,那么您就可以开始了。

    第二种可能性是只在子级上公开一个父级可以调用的方法(父级已经有对子级的引用——你没有在这里引入不必要的耦合),然后简单地调用它而不是调度事件。

    【讨论】:

    • 同意第一种方法。我通常也会做类似的事情,但我想我会先给出一个更简单的答案。 IMO 第二种方法确实在视图的层次结构中创建了耦合。如果我想将comp2 移动到另一个位置(比如我想重构它以便它嵌套在另一个自定义组件中),那会破坏代码。
    • 是的,但您可能已经有一个变量引用它,必须将其删除。因此,无论以哪种方式移动该组件都需要额外的工作。重要的是组件本身不需要更改。但我同意事件总线是要走的路,你的建议甚至可以以这种方式开始实施,然后再进行更改。