views:

28

answers:

1

I have a number of value objects and I want to be able to create a function within it to trace out the properties and the values without specifying them directly. It will allow me to use the same code in all value objects as opposed to referring to variables within the value object. Ideally, I would like to replace the code in blogURLVars with this code.

Here's a sample value object

package items {

public class Blog {

    private var _itemID:uint;
    private var _blogTitle:String;
    private var _blogText:String;
    private var _blogCreated:String;
    private var _blogCategory:String;
    private var _blogFrontpage:Boolean;

    public function Blog (itemID:uint,blogTitle:String,blogText:String,blogCategory:String,blogCreated:String,blogFrontpage:Boolean=false) {

        _itemID = itemID;
        _blogTitle = blogTitle;
        _blogText = blogText;
        _blogCreated = blogCreated;
        _blogCategory = blogCategory;
        _blogFrontpage = blogFrontpage;
    }

    public function get itemID():uint {
        return _itemID;
    }

    public function get blogTitle():String {
        return _blogTitle;
    }

    public function get blogText():String {
        return _blogText;
    }

    public function get blogCategory():String {
        return _blogCategory;
    }

    public function get blogCreated():String {
        return _blogCreated;
    }

    public function get blogFrontpage():Boolean {
        return _blogFrontpage;
    }

    public function toString():void {

    }

    public function blogURLVars():String {
        var s:String;
        s = "itemID="+ _itemID;
        s += "blogTitle="+ _blogTitle;
        s += "blogText="+ _blogText;
        s += "blogCategory="+ _blogCategory;
        s += "blogCreated="+ _blogCreated;
        s += "blogFrontpage="+ _blogFrontpage;
        return s;
    }

}

}

+2  A: 

DescrybeType could be of help here. I'm basing this answer in this other answer (you might want to check it out): http://stackoverflow.com/questions/3540003/fastest-way-to-get-an-objects-values-in-as3/3540117#3540117

Basically, the describeType function will let you inspect the public interface of your object. That means public variables, getter/setters and methods (plus some other info not relevant to your problem). So you get a list of all the getters and with that, return the names of said properties plus their actual values for a given object. Not that this is not exactly the same as your sample code, since this will not use the private variables, but rather will call the getters.

In code, this could be something like this (based on code in the linked question).

package  {
    import flash.net.URLVariables;
    import flash.utils.describeType;
    import flash.utils.getQualifiedClassName;

    public class PropertiesHelper {

        public function PropertiesHelper() {

        }

        private static var typePropertiesCache:Object = {};

        public static function getPropertyNames(instance:Object):Array {
            var className:String = getQualifiedClassName(instance);
            if(typePropertiesCache[className]) {
                return typePropertiesCache[className];
            }
            var typeDef:XML = describeType(instance);
            trace(typeDef);
            var props:Array = [];
            for each(var prop:XML in typeDef.accessor.(@access == "readwrite" || @access == "readonly")) {
                props.push(prop.@name);
            }   
            return typePropertiesCache[className] = props;
        }

        public static function getNameValuePairs(instance:Object):URLVariables {
            var props:Array = getPropertyNames(instance);
            var vars:URLVariables = new URLVariables();
            for each(var prop:String in props) {
                vars[prop] = instance[prop];
            }
            return vars;
        }
    }

}

Use:

        var blog:Blog = new Blog(1,"title&","text","cat","created");
        var urlVars:URLVariables = PropertiesHelper.getNameValuePairs(blog);
        trace(urlVars);

I'm using a URLVariables object since it seems that's what you want (though not actually what you blogURLVars method does), but you could change that in the getNameValuePairs method to suit your needs if necessary. An advantage of using a URLVariables object is that it handles the url-encoding for you automatically, so reserved characters such as &, =, etc, should not be a problem.

Juan Pablo Califano
Wow, this is quite helpful. I can use this in many projects and it will save me so much time. I am going to have to take a closer look to figure it out, but I tested it in my project and it works perfectly. It is class to parse any value object and return the URLVars with property and value. I am so thankful. There is one minor mistake: the function getNameValuePairs should return URLVariables, not Object. I really appreciate your time to respond with the example.
mike
@mike. Fixed! I originally wrote the code to return an Object (and later changed to URLVariables, but forgot to change the return type). I'm glad you find this helpful. You could adapt it to return your data in different formats, if necessary, but the idea remains the same. You inspect your object structure with descrybeType, then cache it (although not necessary, it's cheap and can improve performance), and finally use that structure to inspect the actual object values.
Juan Pablo Califano