tags:

views:

219

answers:

2

In an AIR application, I have a private variable and a setter:

private var _saveResult
public function set saveResult( result:String ):void
{
 _saveResult = result;
 dispatchEvent( new resultUpdatedEvent( _saveResult ));
}

The first time that I set "saveResult" the event fires. But it will never fire again unless I restart the application.

If I change the setter to:

public function set saveResult( result:String ):void
{
 _saveResult = result;
 if ( result != null)
 {
  dispatchEvent( new resultUpdatedEvent( _saveResult ));
 }
}

The problem goes away, I can set the variable many times and the event fires every time.

My question:

Am I doing something wrong here? If not, can anyone explain to me whats happening? If so, what SHOULD I be doing?

Thanks!

+3  A: 

It looks like you're constructing your event incorrectly. The first parameter of an Event object should always be a string. So in this case you'd want to always use the same string so you could listen for the event. What does your resultUpdatedEvent class look like? You'll want it to look something like this:

package myEvents
{
    import flash.events.Event;

    public class PropertyChangeEvent extends Event
    {
        public static const PROPERTY_CHANGE:String = "propertyChange";

        public var result:String = "";

        // Public constructor.
        public function PropertyChangeEvent (type:String, 
            result:String="") {
                // Call the constructor of the superclass.
                super(type);

                // Set the new property.
                this.result= result;
        }


        // Override the inherited clone() method.
        override public function clone():Event {
            return new PropertyChangeEvent(type, result);
        }
    }
}

That way, when you go to dispatch your event, you can construct the event as follows:

new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE, result);

That way, you're listening for the event "PropertyChangeEvent.PROPERTY_CHANGE", which never changes. The problem is now your event listener is probably listening for an event represented by the string saved in result, and obviously, this changes after the first time it's set, so there's no way to assign a listener to it.

For more information about how events work in AS3: http://livedocs.adobe.com/flex/3/html/help.html?content=events%5F02.html

quoo
@quoowow. Good call! I WAS constructing my event incorrectly, thank you for the tip. :DBut now I am calling the constructor correctly and still have the problem.AND I found it.If I have a getter and a setter function with the same name (saveResult) then I can call the setter ONCE, any subsequent calls just silently do nothing. Turns out that it wasn't an event bug, but I learned something about events anyway, so thanks. I must be doing something wrong with my setter/getter, but I can't see any issue.
PaulC
Are you sure you are setting different values. If you set the same value, Flex will ignore it (to save binding time).
ZaBlanc
@ZaBlanc only if the property is `[Bindable]`, right?
Amarghosh
@Amarghosh Correct, or if the entire class is [Bindable], which of course was the problem. :| SO, remove [Bindable], now I cant dispatchEvent, so implemented IEventDispatcher.http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/events/IEventDispatcher.htmlI should have Googled more before posting. Thanks for the pointers. :D
PaulC
+1  A: 

Per the comments... There was no event dispatcher problem. I misdiagnosed the problem, the REAL problem was that if you have a [Bindable] property and you use a setter, and you set it for the current value, flex will ignore it. SO, you have several choices:

1) give the getter and setter different names. Seems like a "bad idea" but it does fix the problem.

2) remove [Bindable] from either the class (my problem) or the property. If the class does not implement IEventDispatcher, you will need to do so. You can simply "extends Sprite" to see it work, but that seems like a "bad idea" as a solution, so I implemented IEventDispatcher per the example at the end of this page: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/events/IEventDispatcher.html

3) I am sure that there is a way to get around this bug, but I don't actually NEED the class to be [Bindable] so I did not find a work around.

PaulC