diff options
author | xue <> | 2006-04-15 14:21:40 +0000 |
---|---|---|
committer | xue <> | 2006-04-15 14:21:40 +0000 |
commit | b07499534b6d0ed57a2b80c4d95354ca3791c236 (patch) | |
tree | 29bfeefb0b543abee915dd4051652dabb413005a /framework/Web/UI/TControl.php | |
parent | 0f380cd025dd9530b8faee7061d1957c5fd6cd9c (diff) |
Breaking change! Changed context of the expressions in template to the template control. Evaluations of <%= %> are now all in PreRender stage.
Diffstat (limited to 'framework/Web/UI/TControl.php')
-rw-r--r-- | framework/Web/UI/TControl.php | 143 |
1 files changed, 141 insertions, 2 deletions
diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php index 7b22760f..2a3a6a30 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
@@ -721,7 +722,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 }
/**
+ * 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.
*/
public function dataBind()
@@ -759,8 +773,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));
}
}
@@ -1157,6 +1187,8 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable {
if($this->_stage<self::CS_LOADED)
{
+ if(($context=$this->getTemplateControl())===null)
+ $context=$this;
if(isset($this->_rf[self::RF_ADAPTER]))
$this->_rf[self::RF_ADAPTER]->onLoad(null);
else
@@ -1165,8 +1197,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<self::CS_LOADED)
$this->_stage=self::CS_LOADED;
@@ -1178,6 +1212,8 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable */
protected function preRenderRecursive()
{
+ $this->autoDataBindProperties();
+
if($this->getVisible(false))
{
$this->ensureChildControls();
@@ -1188,8 +1224,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;
@@ -2016,4 +2056,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 <qiang.xue@gmail.com>
+ * @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 |