Dynamic Flash

Confessions of a serial code abuser
  • rss
  • Home
  • MTASC
  • Archives
  • About me
  • Goodies
    • Base64 encoder/decoder class
  • My Bookshelf
  • My Talks

Searching for a worthy US charity

Wednesday, 20 December 2006

Every year Yahoo! gives its employees a Christmas present. In the past we’ve received fleeces, blankets and sleeping bags, but this year we’ve been allocated an amount of money to donate to a charity of our choice. We can donate to any US registered charity, including the likes of Amnesty International and Greenpeace - but I would like to donate the money to a smaller charity where the impact will be greater.

Since I don’t live in the US, I thought I’d turn to you to see if anyone out there knows of a small, worthy charity that does good work for children. Leave a comment and I’ll check them all out and choose one from your suggestions.

Many thanks, and Happy Christmas :)

Update

So I’ve decided to donate to the Make-A-Wish Foundation of America. Not quite the small charity I was hoping for, but these people do some really good work in the UK with terminally ill children.

Comments
2 Comments »
Categories
General, Yahoo!
Comments rss Comments rss
Trackback Trackback

Where is Flash Debug Player v9.0.28.0 for Intel OS X?

Sunday, 10 December 2006

As an Intel Mac OS X user I’m starting to feel like a second-class netizen - either that or I’m just too stupid to navigate to the download for the Intel / Universal version of the Flash Debug Player 9.0.28.0. The Macintosh Flash Player 9 plugin content debugger link on the Adobe Flash Player - Downloads page is for PowerPC only. I even tried downloading Flex Builder 2 Beta and Flex 2 SDK again, but the former comes with an old Universal Binary version and the latter is still shipping with the PowerPC-only installer.

If anyone out there has managed to track down this beastie, or if someone from Adobe happens to know where it’s been buried on the Adobe website, please let me know.

Comments
12 Comments »
Categories
Flash, Flex 2
Comments rss Comments rss
Trackback Trackback

Databinding to read-only properties in Flex 2

Databinding has to be just about one of the coolest features in Flex 2, allowing you to bind a property to the value of a property of another object. When the property of that object is updated, the value of the bound property will automatically be updated. This is mainly used in Flex to update UI components when the data for the model changes.

Unfortunately databinding doesn't work for read-only properties. A read-only property (by my definition) is a private instance variable of a class that has a getter function without a matching setter function. Something like this:

PLAIN TEXT
Actionscript:
  1. package {
  2.   public class User() {
  3.  
  4.     public function User(name:String):void {
  5.       this._name = name;
  6.     }
  7.  
  8.     private var _name:String;
  9.  
  10.     [Bindable]
  11.     public function get name() {
  12.       return this._name;
  13.     }
  14.  
  15.     public function addTitle(title:String):void {
  16.       this._name = title + " " + this._name;
  17.     }
  18.   }
  19. }

Here the name property of the User class is read-only from outside of the class. This is useful if you won't want other developers (or other classes) from messing with the values of an object, and in doing so helps you to property encapsulate your data and logic. I've also concocted an addTitle method that changes the value of the name property, just so we have something to call to demonstrate databinding.

To make the name property bindable I've added the [Bindable] metadata tag just before the getter function. The [Bindable] metadata tag is used to enable properties to be used as the source of databinding operations, and the Flex compiler picks up on this metadata tag and adds in some extra code to your class to implement data binding at compile time.

This looks as though it might work, but sadly it doesn't. You'll get the following warning from the compiler:

[Bindable] on read-only getter is unnecessary and will be ignored.

While I disagree whole-heartedly with that statement - if it was unnecessary we wouldn't be trying to bind to it - I can see where they're coming from. (Note to Adobe: This is what happens when you let programmers write error messages). The reason it doesn't work is that databinding requires a matching setter function - and for that setter function to be used internally whenever changing the property value - in order to detect changes. As mentioned earlier, the Flex compiler adds code to your class that fires an event whenever the setter function is invoked. Without this event there's no way for anything bound to that property to know it has changed.

The solution to this problem is to define your own databinding event and manually dispatching that event whenever you change the private property. You specify the event name as part of the [Bindable] metadata tag, and you'll need to have your class extend EventDispatcher or one of its sub-classes to use the dispatchEvent method to dispatch your event.

There's an event specifically defined for this purpose: PropertyChangeEvent.PROPERTY_CHANGE. This is the same event type that Flex uses internally when it generates the data binding code, so if it's good enough for Flex it's good enough for us. This class has a static createUpdateEvent method where you can supply the necessary properties - the object dispatching the event, the name of the property changed, the old value and the new value - and get back a PropertyChangeEvent object you can pass to dispatchEvent.

PLAIN TEXT
Actionscript:
  1. package {
  2.   import flash.events.EventDispatcher;
  3.   import mx.events.PropertyChangeEvent;
  4.  
  5.   public class User() {
  6.  
  7.     public function User(name:String):void {
  8.       this._name = name;
  9.     }
  10.  
  11.     private var _name:String;
  12.  
  13.     [Bindable(event="propertyChange")]
  14.     public function get name() {
  15.       return this._name;
  16.     }
  17.  
  18.     public function addTitle(title:String):void {
  19.       var oldName:String = this._name;
  20.  
  21.       this._name = title + " " + this._name;
  22.  
  23.       if (oldName !== this._name) {
  24.         this.dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "name", oldName, this._name));
  25.       }
  26.     }
  27.   }
  28. }

Notice that I'm checking to see that the value of the name property really has changed before dispatching the event, which means the databinding mechanism isn't unnecessarily invoked. In this case it wasn't strictly necessary since we know that the property will always have changed, but it's a good habit to get into.

This looks a bit messy though, and it'll only get worse as you discover more places in your code where this property needs to be updated. What I do is add a private setPropertyName method that I can use whenever I want to change the properties value:

PLAIN TEXT
Actionscript:
  1. package {
  2.   import flash.events.EventDispatcher;
  3.   import mx.events.PropertyChangeEvent;
  4.  
  5.   public class User() {
  6.  
  7.     public function User(name:String):void {
  8.       this._name = name;
  9.     }
  10.  
  11.     private var _name:String;
  12.  
  13.     [Bindable(event="propertyChange")]
  14.     public function get name() {
  15.       return this._name;
  16.     }
  17.  
  18.     private function setName(val:String):void {
  19.       if (this._name !== val) {
  20.         var oldName:String = this._name;
  21.         this._name = val;
  22.         this.dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "name", oldName, val));
  23.       }
  24.     }
  25.  
  26.     public function addTitle(title:String):void {
  27.       this.setName(title + " " + this._name);
  28.     }
  29.   }
  30. }

There, much better.

Using the PropertyChangeEvent class has another added benefit, which is that ArrayCollection objects (and possible others) listen out for this event on the items they contain and broadcast their own databinding events. If we'd used a custom Event class, the containing ArrayCollection wouldn't have known anything had changed and any UI control bound to that ArrayCollection would not have been updated.

I've created a simple demonstration of this technique in action (view source) which you can also download.

Update

Having just ran the above example if debug mode I've noticed that you get a "warning: unable to bind to property 'name' on class 'User'" in the console, which I thought was a bit strange since the example works just fine.

It turns out that Flex is trying to set up 2-way databinding so that any changes in the UI components are reflected in the binding source object (i.e. User). Because our User class is read-only, Flex cannot set up the reverse binding, and that's where the warning is coming from.

The moral of the story is that you can ignore these warnings if they're given on read-only properties.

Comments
15 Comments »
Categories
Flash, Flex 2
Comments rss Comments rss
Trackback Trackback

About Dynamic Flash

Steve Webster is a Senior Web Developer for Yahoo! in London, UK.

He is more than a little concerned that he defines himself in terms of his career, and that he talks about himself in the third person.

Find out more

Recent Posts

  • Yahoo! London seeks Junior Developers
  • I am Singularity
  • Yahoo! Astra component library 1.1 released
  • On X-UA-Compatible
  • foundationas3.com has launched

Tags

ActionScript actionscript 3.0 air book conference designer filereference file upload Flash flex internet internet explorer jobs junior microsoft opportunities singularity08 skin urlrequest web developer web development Web Standards Yahoo!

Stuff

Singularity?
Flex.org - The Directory for Flex
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox