| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You under the Apache License, Version 2.0 |
| // (the "License"); you may not use this file except in compliance with |
| // the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| package mx.binding |
| { |
| |
| import flash.events.Event; |
| import mx.core.IRepeaterClient; |
| import mx.core.mx_internal; |
| |
| use namespace mx_internal; |
| |
| [ExcludeClass] |
| |
| /** |
| * @private |
| */ |
| public class RepeatableBinding extends Binding |
| { |
| include "../core/Version.as"; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Create a Binding object |
| * |
| * @param document The document that is the target of all of this work. |
| * |
| * @param srcFunc The function that returns us the value |
| * to use in this Binding. |
| * |
| * @param destFunc The function that will take a value |
| * and assign it to the destination. |
| * |
| * @param destString The destination represented as a String. |
| * We can then tell the ValidationManager to validate this field. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function RepeatableBinding(document:Object, srcFunc:Function, |
| destFunc:Function, destString:String) |
| { |
| super(document, srcFunc, destFunc, destString); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Execute the binding. |
| * Call the source function and get the value we'll use. |
| * Then call the destination function passing the value as an argument. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function execute(o:Object = null):void |
| { |
| if (isExecuting) |
| return; |
| |
| isExecuting = true; |
| |
| // o is an array index, a single instance of a UIComponent, |
| // a Repeater, or is null. |
| // If it is a number it is because a Watcher fired |
| // and we are being passed the cloneIndex |
| // If it is defined as an Object, it is because the Binding Manager |
| // just called executeBindings() on that particular instance, |
| // and passed it in. |
| // If it is null (now unlikely for RepeatableBinding) a watcher |
| // has just fired and we will execute this RepeatableBinding |
| // on all repeated instances of the object specified by |
| // the _destString of this RepeatableBinding. |
| // For example, if the _destString is "b.label", we update |
| // all instances with id "b", which we locate via their indexed |
| // id references on the document, such as b[2][4]. |
| var id:String; |
| if (!o) |
| { |
| id = destString.substring(0, destString.indexOf(".")); |
| o = document[id]; |
| } |
| else if (typeof(o) == "number") |
| { |
| id = destString.substring(0, destString.indexOf(".")); |
| var components:Array = document[id] as Array; |
| if (components) |
| o = components[o]; |
| else |
| o = null; |
| } |
| |
| if (o) |
| recursivelyProcessIDArray(o); |
| |
| isExecuting = false; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private function recursivelyProcessIDArray(o:Object):void |
| { |
| // o is either a scalar id reference (to a UIComponent or a Repeater) |
| // or an array, perhaps multi-dimensional, of id references |
| |
| if (o is Array) |
| { |
| var array:Array = o as Array; |
| var n:int = array.length; |
| for (var i:int = 0; i < n; i++) |
| { |
| recursivelyProcessIDArray(array[i]); |
| } |
| } |
| else if (o is IRepeaterClient) |
| { |
| var client:IRepeaterClient = IRepeaterClient(o); |
| |
| wrapFunctionCall(this, function():void |
| { |
| var value:Object = wrapFunctionCall(this, srcFunc, null, client.instanceIndices, client.repeaterIndices); |
| |
| if (BindingManager.debugDestinationStrings[destString]) |
| { |
| trace("RepeatableBinding: destString = " + destString + ", srcFunc result = " + value); |
| } |
| |
| destFunc(value, client.instanceIndices); |
| }, |
| o); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event handlers |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * The only reason a Binding listens to an event |
| * is because it wants a signal to execute |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function eventHandler(event:Event):void |
| { |
| if (isHandlingEvent) |
| return; |
| isHandlingEvent = true; |
| |
| execute(); |
| |
| isHandlingEvent = false; |
| } |
| } |
| |
| } |