Oct 01 2008

Using ChangeWatcher

Published by at 9:41 am under Flex


Data binding is one of the best things about Flex, frameworks like Cairngorm rely heavily on data binding. But what if you want to detect a change in variable value and then also do something else. Changewatcher comes in handy during times like those.

 

import mx.binding.utils.ChangeWatcher;

 

This is the class i am talking about, it lets you listen for changes in a variable. Lets say we have a class variable totalItems and we need to detect changes to that variable. This is a simple class.

 

package {

    class Model {
        //i shall leave the constructor to you

        [Bindable]
        public var totalItems:Number;

    }
}

Now to detect changes to this variable, the code would look something like,

import mx.binding.utils.ChangeWatcher;

public var watcherInstance:ChangeWatcher;

[Bindable]
public var model:Model;

public function init():void{

//this is useful if you want to unwatch or stop detecting changes to this variable
//ofcourse init function has to be called
model = new Model();
watcherInstance = ChangeWatcher.watch(model,["totalItems"],itemsChanged);

}

public function itemsChanged(event:PropertyChangeEvent):void{
//this function is called as soon as value of totalItem changes.
//if you want to stop watching this variable.
watcherInstance.unwatch();
}

So you can see that this is very easy way of detecting changes, the only thing to keep in mind is that the variables being watched have to be Bindable. You can also detect changes within chain of classes.

 

For Eg. ChangeWatcher.watch(model,[“shoppingCart”,”totalItems”],itemsChanged); the variable totalItems is inside the class ShoppingCart which is initialized in Model. So your chain of variables can be as long as you want.

 

Other Important thing to note is that the line code after the variable will be executed only after your listener function is called. Its not asynchronous like URLLoader etc.

 

EDIT: 02/20/09 Imp Note:

If you are tracking changes to a number, your changewatcher function will fire only if the number changes. Lets say your variable totalItems is 1 and after performing some calculation its again 1, in this situation your changewatcher won’t fire because the value of variable hasn’t changed. It can cause crazy bugs in your application and i have been bitten by this couple of times now. 

 

The example below shows how you can watch a chain and also how every variable has to be bindable etc.

Click here for the source.

 

 

8 responses so far

8 Responses to “Using ChangeWatcher”

  1. Mohammed Fasilon 25 Oct 2009 at 11:40 pm

    Hi,

    The information provided was really helpful.
    What if I want to check if an array collection got changed in the model?

    Is it possible?

    One of possible ways I know is
    ChangeWatcher.watch(model,[“arraycollection”, “length”],itemsChanged);

    The above works but its not necessary that lenght should always change it can the be the data which got changed. Is it possible to be detected using changeWatcher?

  2. Nayanon 26 Oct 2009 at 11:23 am

    for all the collection classes there is collectionChange event broadcasted which you can use to detect changes within the collection object. you don’t have to use Changewatcher for it.

  3. Shannaraon 17 Dec 2009 at 10:51 am

    BTW: I found out the hard way that this watcher is only partially implimented in Flex 3.x. You can NOT watch booleans with this, it breaks, and doesnt do a thing.

  4. Nayanon 17 Dec 2009 at 11:21 am

    changewatcher uses propertychangeevent, so it might not work with certain properties. if the property is not bindable and public/accessible by outside classes then changewatcher won’t be able to watch it as simple as that.

    you can make a boolean watchable but it has to be a public property of the object and it has to be bindable, you can see for urself in the following example.

    < ?xml version="1.0" encoding="utf-8"?>


    < ![CDATA[ import mx.binding.utils.ChangeWatcher; import mx.events.FlexEvent; import mx.events.PropertyChangeEvent; [Bindable] public var checkBool:Boolean = false; private var watcher:ChangeWatcher; protected function application1_creationCompleteHandler(event:FlexEvent):void { // TODO Auto-generated method stub watcher = ChangeWatcher.watch(this,["checkBool"],selectedCheckbox); } public function selectedCheckbox(event:PropertyChangeEvent):void{ checkBox.selected = checkBool; } protected function button1_clickHandler(event:MouseEvent):void{ // TODO Auto-generated method stub if (inputText.text.length > 2){
    checkBool = true;
    } else {
    checkBool = false;
    }
    trace(checkBool);
    }

    ]]>



    if you change the checkBool to private its not going to work. enjoy.

  5. Omar Mostafaon 07 Dec 2010 at 4:48 am

    Thanks for the nice article, the code snippet is also very useful

    Regards,
    Omar Mostafa

  6. Praveen Nimmakayalaon 04 Apr 2012 at 12:29 am

    Very nice example to get good understanding on ChangeWatcher. Thank u so much.

  7. Praveen Nimmakayalaon 04 Apr 2012 at 12:31 am

    Also it is some what high end, with out the three controls, like textInput, checkbox, and Button. For new people it may be some what tough to follow. Any how thanks for your work.

  8. Manu Mohanon 25 Sep 2012 at 10:00 pm

    Thanks for the info, a very good info…

Trackback URI | Comments RSS

Leave a Reply