blob: 76b8b009b48733648125a481e52c51d3ba01f582 [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
}
}