3

I have a dynamic Class and what I would like to do is call a method everytime a property is appended to the class during run-time.

For example:

dynamic class Example
{

    public function Example()
    {
        trace("New instance created");
    }

    public function setter(name:String, value:String):Void
    {
        trace("Property '"+name+"' created with value '"+value+"'");
    }
}

And then from the timeline when I would add a new property to Example:

Example.newProperty = "some value";

I want it to trace:

Property 'newProperty' created with value ' some value'

I am fully aware that this is capable by using a function to set properties like so:

public function setter(name:String, value:String):Void
{
    this[name] = "some value";
    trace("Property '"+name+"' created with value '"+value+"'");
}

and calling it like so:

Example.setter("newProperty", "some value");

However I want this method to fire automatically when a property is added via the regular .dot operator and not have to call a function explicitly.

Is this possible?

George Reith
  • 13,132
  • 18
  • 79
  • 148

2 Answers2

1

Since it's AS2, then, yes, your class has to implement __resolve(x) method. I would, however, consider it a very questionable design decision. The function that accepts the key and the value looks much better to me, and, in the end, it's less code.

  • Questionable maybe, but I am building the class so that it can be used by others as simply as possible. I thought `__resolve` is when someone attempts read an unassigned property of an object not to call a function when one is assigned no? – George Reith Feb 08 '12 at 09:38
  • I am not attempting to store a function as the property, and won't be calling the property at a later time. What I want is for the instance to perform a method (already defined in the Class) when a previously undefined property is set. In this case it is for a dropdown class and so that someone can add a new dropdown option to the list at any point by saying `dropdown.newOption = "blah blah"`, then a method would run to draw and assign the new option to the dropdown. – George Reith Feb 08 '12 at 10:37
  • `__resolve(x)` isn't called unless you attempt to use an undefined paramater e.g. `trace(example.something);` when `example.something` isn't set. It isn't called if I attempt `example.something = "value"`. Also the method is 100% easier for the people I am designing it for to use, they are not programmers and don't care for the structure or what the true intent of the code should be. The syntax is much easier for them to understand and code with. – George Reith Feb 08 '12 at 11:40
  • Because the property is not meant to be read. It is purely to run the function. I understand what you are saying but you assume too much knowledge of who this is for. They are designers with basic actionscript capabilities e.g. `movieclip = this.movieclip`. Named functions are a stretch for them. This would make a very easy syntax using operators they are familiar with to add buttons to the dropdown. `dropdown.option4 = "hello"`. This isn't about best practice but what is useful for the situation. – George Reith Feb 08 '12 at 13:57
  • I am a graphic artist too, I know who I am making it for personally. This is what they want. I'm not misusing the assignment operator, im still asigning a property with it, I just want a function to run automatically once that property is assigned. This is my requirements and what I'm going to build. – George Reith Feb 08 '12 at 14:42
0

Could use Proxy here.

Example class:

package
{
    import flash.utils.Proxy;
    import flash.utils.flash_proxy;

    dynamic public class Example extends Proxy
    {

        private var _properties:Object = {};


        override flash_proxy function setProperty(name:*, value:*):void
        {
            _properties[name] = value;
            trace("Property '" + name + "' created with value '" + value + "'");
        }


        override flash_proxy function getProperty(name:*):*
        {
            return _properties[name];
        }

    }
}

Demo code:

var ex:Example = new Example();

ex.something = 10;
ex.more = "something more";

trace(ex.something);
trace(ex.more);

Output:

Property 'something' created with value '10'
Property 'more' created with value 'something more'
10
something more

Marty
  • 39,033
  • 19
  • 93
  • 162