views:

272

answers:

4

In my flex app I have a public bindable property. I want it so that every time the value of that property changes, a function gets triggered. I tried using ChangeWatchers, but it seems those only apply to built-in components like a text box change. I would like to do that same behavior with a property that changes at runtime.

A: 

well, the easiest way is to listen to PropertyChangeEvent.PROPERTY_CHANGE ... if you declare a property bindable, then mxmlc generates the code to dispatch this event ... if you let the compiler keep the generated ActionScript, then you'll see it ...

other than that, you might want to have a look at BindingUtils ...

greetz

back2dos

back2dos
A: 

Look into BindUtils class as back2dos suggests.

And, also, you can set the name of the event that will be triggered when a change is done to a property (default is propertyChange) like this:

[Bindable("change")]
var myProperty : SomeClass;

That is if ChangeWatchers adds listeners for the change event instead of propertyChange event. Which would be kind of weird, but not impossible with all the mishaps of the flex SDKs.

But again, I think BindUtils class should do the trick for you.

bug-a-lot
+2  A: 

One option is to use BindingUtils.bindSetter (which incidentally returns a ChangeWatcher):

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="this_creationComplete()">

    <mx:Script>
     <![CDATA[

      import mx.binding.utils.BindingUtils;
      import mx.binding.utils.ChangeWatcher;

      [Bindable]
      public var myValue:int = 0;

      private function this_creationComplete():void
      {
       var cw:ChangeWatcher = BindingUtils.bindSetter(myValueChanged, this, "myValue");
      }

      private function setValue():void
      {
       myValue = getTimer();
      }

      private function myValueChanged(o:Object):void
      {
       trace("myValue: " + myValue.toString());

       // You can also use o.toString() -- the new value will be passed into the function
      }

     ]]>
    </mx:Script>


    <mx:Button label="Click Me" click="setValue()" />

</mx:Application>

Here, myValueChanged gets called whenever the myValue property changes. There are other ways, of course, but I often use this approach with good results. Hope it helps! Post back with questions and I'll keep an eye out.

Christian Nunciato
A: 

Use the class ObjectProxy or its subclass and wrap up the class that has a property you need to watch. In my example, I'm calling a func if someone is changing the property salary giving it a value of more than 55000 in an object Person:

package com.farata { import mx.utils.ObjectProxy; import flash.utils.*;

use namespace flash_proxy;

public dynamic class MyPersonProxy extends ObjectProxy
{
// The object to wrap up
private var person:Person;

 public function MyPersonProxy(item:Person){
  super(item);
  person=item;
 }

  flash_proxy override function setProperty(name:*, value:*):void {

if ( name == 'salary'&& value>55000) { // add a new property to this instance of the // class Person, which can be used in the calculations // of the total compensation setProperty("pension", 0.02); } super.setProperty(name, value);
} } }

Yakov Fain