From 70944795827cffd1bd5a27a9c4a99eb1434f905f Mon Sep 17 00:00:00 2001 From: xue <> Date: Sat, 15 Apr 2006 14:35:46 +0000 Subject: Merge from branch 3.0 till 913. --- framework/Web/UI/TControl.php | 143 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 141 insertions(+), 2 deletions(-) (limited to 'framework/Web/UI/TControl.php') diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php index 78c5bdfc..9ede6be5 100644 --- a/framework/Web/UI/TControl.php +++ b/framework/Web/UI/TControl.php @@ -122,6 +122,7 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable const RF_CONTROLSTATE=7; // controlstate const RF_NAMED_OBJECTS=8; // controls declared with ID on template const RF_ADAPTER=9; // adapter + const RF_AUTO_BINDINGS=10; // auto data bindings /** * @var string control ID @@ -722,7 +723,7 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable /** * Sets up the binding between a property (or property path) and an expression. - * The context of the expression is the control itself. + * The context of the expression is the template control (or the control itself if it is a page). * @param string the property name, or property path * @param string the expression */ @@ -740,6 +741,19 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable unset($this->_rf[self::RF_DATA_BINDINGS][$name]); } + /** + * Sets up the binding between a property (or property path) and an expression. + * Unlike regular databinding, the expression bound by this method + * is automatically evaluated during {@link prerenderRecursive()}. + * The context of the expression is the template control (or the control itself if it is a page). + * @param string the property name, or property path + * @param string the expression + */ + public function autoBindProperty($name,$expression) + { + $this->_rf[self::RF_AUTO_BINDINGS][$name]=$expression; + } + /** * Performs the databinding for this control. */ @@ -760,8 +774,24 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable { if(isset($this->_rf[self::RF_DATA_BINDINGS])) { + if(($context=$this->getTemplateControl())===null) + $context=$this; foreach($this->_rf[self::RF_DATA_BINDINGS] as $property=>$expression) - $this->setSubProperty($property,$this->evaluateExpression($expression)); + $this->setSubProperty($property,$context->evaluateExpression($expression)); + } + } + + /** + * Auto databinding properties of the control. + */ + protected function autoDataBindProperties() + { + if(isset($this->_rf[self::RF_AUTO_BINDINGS])) + { + if(($context=$this->getTemplateControl())===null) + $context=$this; + foreach($this->_rf[self::RF_AUTO_BINDINGS] as $property=>$expression) + $this->setSubProperty($property,$context->evaluateExpression($expression)); } } @@ -1159,6 +1189,8 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable { if($this->_stagegetTemplateControl())===null) + $context=$this; if(isset($this->_rf[self::RF_ADAPTER])) $this->_rf[self::RF_ADAPTER]->onLoad(null); else @@ -1167,8 +1199,10 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable if($this->getHasControls()) { foreach($this->_rf[self::RF_CONTROLS] as $control) + { if($control instanceof TControl) $control->loadRecursive(); + } } if($this->_stage_stage=self::CS_LOADED; @@ -1180,6 +1214,8 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable */ protected function preRenderRecursive() { + $this->autoDataBindProperties(); + if($this->getVisible(false)) { $this->ensureChildControls(); @@ -1190,8 +1226,12 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable if($this->getHasControls()) { foreach($this->_rf[self::RF_CONTROLS] as $control) + { if($control instanceof TControl) $control->preRenderRecursive(); + else if($control instanceof TCompositeLiteral) + $control->evaluateDynamicContent(); + } } } $this->_stage=self::CS_PRERENDERED; @@ -2030,4 +2070,103 @@ class TCommandEventParameter extends TEventParameter } } + +/** + * TCompositeLiteral class + * + * TCompositeLiteral is used internally by {@link TTemplate} for representing + * consecutive static strings, expressions and statements. + * + * @author Qiang Xue + * @version $Revision: $ $Date: $ + * @package System.Web.UI + * @since 3.0 + */ +class TCompositeLiteral extends TComponent implements IRenderable, IBindable +{ + const TYPE_EXPRESSION=0; + const TYPE_STATEMENTS=1; + const TYPE_DATABINDING=2; + private $_container=null; + private $_items=array(); + private $_expressions=array(); + private $_statements=array(); + private $_bindings=array(); + + /** + * Constructor. + * @param array list of items to be represented by TCompositeLiteral + */ + public function __construct($items) + { + $this->_items=array(); + $this->_expressions=array(); + $this->_statements=array(); + foreach($items as $id=>$item) + { + if(is_array($item)) + { + if($item[0]===self::TYPE_EXPRESSION) + $this->_expressions[$id]=$item[1]; + else if($item[0]===self::TYPE_STATEMENTS) + $this->_statements[$id]=$item[1]; + else if($item[0]===self::TYPE_DATABINDING) + $this->_bindings[$id]=$item[1]; + $this->_items[$id]=''; + } + else + $this->_items[$id]=$item; + } + } + + /** + * @return TComponent container of this component. It serves as the evaluation context of expressions and statements. + */ + public function getContainer() + { + return $this->_container; + } + + /** + * @param TComponent container of this component. It serves as the evaluation context of expressions and statements. + */ + public function setContainer(TComponent $value) + { + $this->_container=$value; + } + + /** + * Evaluates the expressions and/or statements in the component. + */ + public function evaluateDynamicContent() + { + $context=$this->_container===null?$this:$this->_container; + foreach($this->_expressions as $id=>$expression) + $this->_items[$id]=$context->evaluateExpression($expression); + foreach($this->_statements as $id=>$statement) + $this->_items[$id]=$context->evaluateStatements($statement); + } + + /** + * Performs databindings. + * This method is required by {@link IBindable} + */ + public function dataBind() + { + $context=$this->_container===null?$this:$this->_container; + foreach($this->_bindings as $id=>$binding) + $this->_items[$id]=$context->evaluateExpression($binding); + } + + /** + * Renders the content stored in this component. + * This method is required by {@link IRenderable} + * @param ITextWriter + */ + public function render($writer) + { + $writer->write(implode('',$this->_items)); + } +} + ?> \ No newline at end of file -- cgit v1.2.3