0

What's the best way(s) to implement a "cancel" button feature (say for a dialog which uses some shared model & two way bindings)?

The obvious solution of copying every field in the object into a "revert" obj defeats the purpose (might as well just set each value manually upon a save). I've used ObjectUtil.copy/clone in the past, but I'm not aware of all the caveats with more complex data types which contain lists, etc. (Deep vs. Shallow copy)

Are there any better/other methods?

Mifune
  • 370
  • 1
  • 5
  • 14
  • I think this question is too vague to be answered. How does the shared model relate to the dialog? What does the Dialog do? What data is being bound (from what and to where?) What do you want to cancel when the button is pressed? – JeffryHouser Sep 21 '12 at 16:12
  • Fair enough questions. It's intentionally generic because I'm interested in general solutions, so I have no specific example prepared. It's just a dialog with for example ComboBoxes, Lists, TextInputs, TextAreas, which allows a user to edit the values used by an application. The values being edited may be simple strings, lists, or more complex composite objects. (Ex. A preferences configuration dialog in Eclipse.) Cancel should revert/ignore all the changes made by the user which occurred since that dialog was opened. – Mifune Sep 21 '12 at 17:04

2 Answers2

1

Please read AS3 - Clone an object

For complex Value Objects will be good using the ByteArray class for creation clone. But make sure that you are using [RemoteClass] or registerClassAlias for all classes that you what to clone.

Community
  • 1
  • 1
Ivan Dyachenko
  • 1,348
  • 9
  • 16
  • Doesn't ObjectUtil.clone() or ObjectUtil.copy() do something similar or the same? (Been awhile since I've looked.) – Mifune Sep 21 '12 at 17:09
  • Yeah - ObjectUtil.copy() does exactly that, but why does it need RemoteClass or registerClassAlias? – Mifune Sep 21 '12 at 17:12
1

I've had issues with the builtin ObjectUtil.clone() and ObjectUtil.copy() methods. Thats why I created my own version that uses introspection instead using ByteArray.

One method copies all properties from one instance to another:

    private static const rw:String = "readwrite";

    public static function copyProperties(source:Object, target:Object):void {
        if (!source || !target) return;

        //copy properties declared in Class definition
        var sourceInfo:XML = describeType(source);
        var propertyLists:Array = [sourceInfo.variable, sourceInfo.accessor];

        for each (var propertyList:XMLList in propertyLists) {
            for each (var property:XML in propertyList) {
                if (property.@access == undefined || property.@access == rw) {
                    var name:String = property.@name;
                    if (target.hasOwnProperty(name)) target[name] = source[name];
                }
            }
        }

        //copy dynamic properties
        for (name in source) 
            if (target.hasOwnProperty(name)) 
                target[name] = source[name];
    }

The other creates a complete clone of an object by copying all its properties to a new instance:

    public static function clone(source:Object):* {
        var Clone:Class = getDefinitionByName(getQualifiedClassName(source)) as Class;
        var clone:* = new Clone();
        copyProperties(source, clone);
        return clone;
    }
RIAstar
  • 11,912
  • 20
  • 37