/**
* Implementation of data binding of Kekule widget (and even other object).
*/
/*
* requires /lan/classes.js
* requires /core/kekule.common.js
* requires /utils/kekule.utils.js
* requires /utils/kekule.domUtils.js
* requires /xbrowsers/kekule.x.js
* requires /widget/kekule.widget.base.js
*/
(function(){
"use strict";
/**
* A binding item between objects.
* @class
* @augments ObjectEx
*
* @param {ObjectEx} source Source object to retrieve data.
* @param {ObjectEx} target Target object to affect by data.
* @param {String} sourceName Appoint how to retrieve data from source, usually a property name.
* @param {String} targetName Appoint how to set data to target, usually a property name.
*
* @property {ObjectEx} source Source object to retrieve data.
* @property {ObjectEx} target Target object to affect by data.
* @property {String} sourceName Appoint how to retrieve data from source, usually a property name.
* @property {String} targetName Appoint how to set data to target, usually a property name.
*/
Kekule.DataBingItem = Class.create(ObjectEx,
/** @lends Kekule.DataBingItem# */
{
/** @private */
CLASS_NAME: 'Kekule.DataBingItem',
/** @constructs */
initialize: function($super, source, sourceName, target, targetName)
{
$super();
this.setSource(source);
this.setSourceName(sourceName);
this.setTarget(target);
this.setTargetName(targetName);
},
/** @private */
initProperties: function()
{
this.defineProp('source', {'dataType': DataType.OBJECTEX, 'serializable': false});
this.defineProp('sourceName', {'dataType': DataType.STRING, 'serializable': false});
this.defineProp('target', {'dataType': DataType.OBJECTEX, 'serializable': false});
this.defineProp('targetName', {'dataType': DataType.STRING, 'serializable': false});
},
/**
* Retrieve data from source and feed to target, or from target to source if reverseDirection is true.
* @param {Bool} reverseDirection
*/
updateData: function(reverseDirection)
{
var src = this.getSource();
var target = this.getTarget();
var srcName = this.getSourceName();
var targetName = this.getTargetName();
if (src && target && srcName && targetName)
{
if (reverseDirection)
{
var data = target.getDataByBindingName(targetName);
src.setDataByBindingName(srcName, data);
}
else
{
var data = src.getDataByBindingName(sourceName);
target.setDataByBindingName(targetName, data);
}
}
}
});
ClassEx.extend(ObjectEx,
/** @lends Kekule.ObjectEx# */
{
/**
* Retrieve data by a binding name.
* Descendants can override this method.
* @param {String} name
*/
getDataByBindingName: function(name)
{
if (this.hasProperty(name)) // is property
return this.getPropValue(name);
else if (DataType.isFunctionValue(this[name])) // is function
return this[name]();
},
/**
* Set data by binding name.
* Descendants can override this method.
* @param {String} name
* @param {Variant} value
*/
setDataByBindingName: function(name, value)
{
var v = value;
var propInfo = this.getPropInfo(name);
if (propInfo) // is property
{
var propType = propInfo.dataType;
var valueType = DataType.getType(value);
if ((propType !== valueType) && (valueType === DataType.STRING)) // need to convert, now only convert string to other type
{
v = DataType.StringUtils.deserializeValue(value);
}
}
this.setPropValue(name, v);
return this;
},
/**
* Create a data binding from src/srcName to this/targetName.
* @param {ObjectEx} src
* @param {String} srcName
* @param {String} targetName
*/
createDataBinding: function(src, srcName, targetName)
{
var result = new Kekule.DataBingItem(src, srcName, this, targetName);
this.getDataBindings(true).push(result);
return result;
},
/**
* Remove a data binding item.
* @param {Kekule.DataBindingItem} bindingItem
*/
removeDataBinding: function(bindingItem)
{
Kekule.ArrayUtils.remove(this.getDataBindings(), bindingItem);
},
/**
* Update all bound data.
* @param {Bool} reverseDirection
*/
updateBindingData: function(reverseDirection)
{
var items = this.getDataBindings();
if (items && items.length)
{
for (var i = 0, l = items.length; i < l; ++i)
{
items[i].updateData(reverseDirection);
}
}
}
});
/*
* data binding
*/
ClassEx.defineProp(ObjectEx, 'dataBindings', {'dataType': DataType.ARRAY,
'scope': Class.PropertyScope.PRIVATE,
'getter': function(canCreate)
{
var result = this.getPropStoreFieldValue('dataBindings');
if (!result && canCreate)
{
result = [];
this.setPropStoreFieldValue('dataBindings', result);
}
return result;
}
});
})();