views:

4021

answers:

3

I'm new to flex , so forgive me if this is a dumb question.

Right now I'm using custom events to pass data from one component to another. My problem is that events only bubble up. How can I pass data to a component that isn't a parent of the component dispatching the event?

Here's the basic layout. I'm trying to get data from component 1 passed to component 3.

Application MXML
     Component 1
     Component 2
          Component 3
+2  A: 

Easiest way is just to access the other component.

<Component1 name="component1/>

<Component2 name="component2" onClick="onClickHandler()"/>

private function onClickHandler(event:MouseEvent):void
{
    component1.property1 = "Random data";
    component1.sendData("Random Data");
}

When you set a bindable public property in component1, it will raise a PropertyChangedEvent, which you can handle as well.

You have a lot of options here, see which one is best in the context of what you are trying to do.

EDIT: Reading further about what I think you're trying to do, you're trying to access component3 from component2, but component3 is not readiily visible to component1? It should still accessible through component2 though, (Components tend to be public members).

private function component1OnClickHandler(event:MouseEvent):void
{
     component2.component3.property1 = "Random data";
}

Hope this helps!

CookieOfFortune
that seems to be working for me. Is it a bad idea if I dispatch an even from a component inside of component 1, catch that in the application MXML, and then set the data in component 3? It works, but it doesn't seem like the best way to do things.
KevMo
never mind, looks like binding the data is the solution I'm after
KevMo
+6  A: 

If a piece of data is required by all components in a graph/tree, your best bet is to expose a public bindable property on each. Let the child components dispatch a bubbling event that is handled by the parent, who can set the new value of the bindable property. If you bind the property from the parent down to the child this will "cascade" down to the other components.

<!-- in root application -->
<Component1 myData="{myData}"/>

If you need to invoke additional logic, you can define a get/set pair instead of public var and add logic to the setter:

[Bindable] private var _myData;
public function set myData(value:Object):void
{
    _myData = value;
    doSomeLogic();
}

Even better would be to use Flex's invalidation framework to optimize performance:

_myDataChanged : Boolean = false;
[Bindable] private var _myData;
public function set myData(value:Object):void
{
    if (_myData != value) {
        _myData = value;
        _myDataChanged = true;
    }
    invalidateProperties();
}

override protected function commitProperties() : void {
    super.commitProperties();
    if (_myDataChanged) {
        _myDataChanged = false;
        doSomeLogic()
    }
}

This pattern is used all over the place in all the UIComponents that make up the Flex framework. You may also need to override updateDisplayList(...) to position elements.

cliff.meyers
ah, that's what I need. I also like that invalidation framework.
KevMo
A: 

hello

can u please explain in more detail.?

twext