From e126c0067e9efee6542d08bf649588e2cf3a5924 Mon Sep 17 00:00:00 2001 From: xue <> Date: Thu, 12 Jan 2006 03:22:03 +0000 Subject: Fixed several issues about viewstate handling. Prado Composer is nearly completed. --- framework/Web/UI/TControl.php | 36 +++++++--------------- framework/Web/UI/TTemplateManager.php | 5 ++- framework/Web/UI/WebControls/TDataBoundControl.php | 5 +-- framework/Web/UI/WebControls/TListControl.php | 19 +++++++++--- framework/Web/UI/WebControls/TRepeater.php | 36 +++++++++++++++++++--- 5 files changed, 62 insertions(+), 39 deletions(-) (limited to 'framework/Web') diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php index db0e141b..18b7d1e0 100644 --- a/framework/Web/UI/TControl.php +++ b/framework/Web/UI/TControl.php @@ -1285,11 +1285,11 @@ class TControl extends TComponent */ final protected function loadStateRecursive(&$state,$needViewState=true) { - // A null state means the stateful properties all take default values. - // So if the state is enabled, we have to assign the null value. - $needViewState=($needViewState && !($this->_flags & self::IS_DISABLE_VIEWSTATE)); - if(is_array($state)) + if($state!==null) { + // A null state means the stateful properties all take default values. + // So if the state is enabled, we have to assign the null value. + $needViewState=($needViewState && !($this->_flags & self::IS_DISABLE_VIEWSTATE)); if(isset($state[1])) { $this->_rf[self::RF_CONTROLSTATE]=&$state[1]; @@ -1324,24 +1324,11 @@ class TControl extends TComponent } if(!empty($state)) $this->_rf[self::RF_CHILD_STATE]=&$state; + $this->_stage=self::CS_STATE_LOADED; + $this->onLoadState(null); } - else - { - unset($this->_rf[self::RF_CONTROLSTATE]); - if($needViewState) - $this->_viewState=array(); - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - $s=null; - if($control instanceof TControl) - $control->loadStateRecursive($s,$needViewState); - } - } - } - $this->onLoadState(null); - $this->_stage=self::CS_STATE_LOADED; + else // no state to load and thus no need onLoadState() + $this->_stage=self::CS_STATE_LOADED; } /** @@ -1361,14 +1348,13 @@ class TControl extends TComponent if($control instanceof TControl) { $cs=&$control->saveStateRecursive($needViewState); - if(!empty($cs)) - $state[$control->_id]=&$cs; + $state[$control->_id]=&$cs; } } } - if($needViewState && !empty($this->_viewState)) + if($needViewState) $state[0]=&$this->_viewState; - if(isset($this->_rf[self::RF_CONTROLSTATE]) && !empty($this->_rf[self::RF_CONTROLSTATE])) + if(isset($this->_rf[self::RF_CONTROLSTATE])) $state[1]=&$this->_rf[self::RF_CONTROLSTATE]; return $state; } diff --git a/framework/Web/UI/TTemplateManager.php b/framework/Web/UI/TTemplateManager.php index b6a9abd8..bd838db2 100644 --- a/framework/Web/UI/TTemplateManager.php +++ b/framework/Web/UI/TTemplateManager.php @@ -231,10 +231,9 @@ class TTemplate extends TComponent implements ITemplate * @param TControl the parent control * @throws TTemplateRuntimeException if an error is encountered during the instantiation. */ - public function instantiateIn($tplControl,$page=null) + public function instantiateIn($tplControl) { - if($page===null) - $page=$tplControl->getPage(); + $page=$tplControl->getPage(); $this->_assetManager=$page->getService()->getAssetManager(); $controls=array(); foreach($this->_tpl as $key=>$object) diff --git a/framework/Web/UI/WebControls/TDataBoundControl.php b/framework/Web/UI/WebControls/TDataBoundControl.php index 7d865e0f..ea2a0602 100644 --- a/framework/Web/UI/WebControls/TDataBoundControl.php +++ b/framework/Web/UI/WebControls/TDataBoundControl.php @@ -40,6 +40,7 @@ abstract class TDataBoundControl extends TWebControl private $_currentDataSourceValid=false; private $_currentViewIsFromDataSourceID=false; private $_parameters=null; + private $_isDataBound=false; /** * @return Traversable data source object, defaults to null. @@ -131,7 +132,7 @@ abstract class TDataBoundControl extends TWebControl */ protected function getIsDataBound() { - return $this->getViewState('IsDataBound',false); + return $this->_isDataBound; } /** @@ -139,7 +140,7 @@ abstract class TDataBoundControl extends TWebControl */ protected function setIsDataBound($value) { - $this->setViewState('IsDataBound',TPropertyValue::ensureBoolean($value),false); + $this->_isDataBound=$value; } /** diff --git a/framework/Web/UI/WebControls/TListControl.php b/framework/Web/UI/WebControls/TListControl.php index f5619b45..7057e119 100644 --- a/framework/Web/UI/WebControls/TListControl.php +++ b/framework/Web/UI/WebControls/TListControl.php @@ -80,7 +80,10 @@ abstract class TListControl extends TDataBoundControl * @var TListItemCollection item list */ private $_items=null; - + /** + * @var boolean whether items are restored from viewstate + */ + private $_loadedFromState=false; /** * @return string tag name of the list control */ @@ -137,7 +140,8 @@ abstract class TListControl extends TDataBoundControl */ public function addParsedObject($object) { - if($object instanceof TListItem) + // Do not add items from template if items are loaded from viewstate + if(!$this->_loadedFromState && ($object instanceof TListItem)) $this->getItems()->add($object); } @@ -190,14 +194,19 @@ abstract class TListControl extends TDataBoundControl } /** - * Loads items into from viewstate. + * Loads items from viewstate. * This method is invoked right after control state is loaded. * @param mixed event parameter */ protected function onLoadState($param) { - $this->_items=new TListItemCollection; - $this->_items->loadState($this->getViewState('Items',null)); + $this->_loadedFromState=true; + if(!$this->getIsDataBound()) + { + $this->_items=new TListItemCollection; + $this->_items->loadState($this->getViewState('Items',null)); + } + $this->clearViewState('Items'); } /** diff --git a/framework/Web/UI/WebControls/TRepeater.php b/framework/Web/UI/WebControls/TRepeater.php index 5110cc75..342a764b 100644 --- a/framework/Web/UI/WebControls/TRepeater.php +++ b/framework/Web/UI/WebControls/TRepeater.php @@ -56,6 +56,10 @@ class TRepeater extends TDataBoundControl implements INamingContainer private $_footer=null; private static $_templates=array(); + public function addParsedObject($object) + { + } + /** * @return string the template string for the item */ @@ -227,8 +231,8 @@ class TRepeater extends TDataBoundControl implements INamingContainer self::$_templates[$key]=$template; } } - $template->instantiateIn($item,$this->getPage()); $this->getControls()->add($item); + $template->instantiateIn($item); } } @@ -250,14 +254,14 @@ class TRepeater extends TDataBoundControl implements INamingContainer return $item; } - protected function createChildControls() + protected function restoreItemsFromViewState() { $this->getControls()->clear(); $items=$this->getItems(); $items->clear(); $this->_header=null; $this->_footer=null; - if(($itemCount=$this->getViewState('ItemCount',null))!==null) + if(($itemCount=$this->getViewState('ItemCount',0))>0) { if($this->_headerTemplate!=='') $this->_header=$this->createItemInternal(-1,'Header',false,null); @@ -275,6 +279,31 @@ class TRepeater extends TDataBoundControl implements INamingContainer $this->clearChildState(); } + /** + * Saves items into viewstate. + * This method is invoked right before control state is to be saved. + * @param mixed event parameter + */ + protected function onSaveState($param) + { + if($this->_items) + $this->setViewState('ItemCount',$this->_items->getCount(),0); + else + $this->clearViewState('ItemCount'); + } + + /** + * Loads items into from viewstate. + * This method is invoked right after control state is loaded. + * @param mixed event parameter + */ + protected function onLoadState($param) + { + if(!$this->getIsDataBound()) + $this->restoreItemsFromViewState(); + $this->clearViewState('ItemCount'); + } + /** * Performs databinding to populate list items from data source. * This method is invoked by dataBind(). @@ -307,7 +336,6 @@ class TRepeater extends TDataBoundControl implements INamingContainer } else $this->setViewState('ItemCount',$itemIndex,-1); - $this->setChildControlsCreated(true); } /** -- cgit v1.2.3