summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxue <>2006-01-12 03:22:03 +0000
committerxue <>2006-01-12 03:22:03 +0000
commite126c0067e9efee6542d08bf649588e2cf3a5924 (patch)
treee1b14841cfdf8f05ce307ff9d63e8d2a466999a7
parenta06e326f247bff617191b1c87a7b004414495275 (diff)
Fixed several issues about viewstate handling. Prado Composer is nearly completed.
-rw-r--r--demos/composer/protected/pages/Home.page45
-rw-r--r--demos/composer/protected/pages/Home.php67
-rw-r--r--framework/Web/UI/TControl.php36
-rw-r--r--framework/Web/UI/TTemplateManager.php5
-rw-r--r--framework/Web/UI/WebControls/TDataBoundControl.php5
-rw-r--r--framework/Web/UI/WebControls/TListControl.php19
-rw-r--r--framework/Web/UI/WebControls/TRepeater.php36
7 files changed, 129 insertions, 84 deletions
diff --git a/demos/composer/protected/pages/Home.page b/demos/composer/protected/pages/Home.page
index b446abd2..ae4149ee 100644
--- a/demos/composer/protected/pages/Home.page
+++ b/demos/composer/protected/pages/Home.page
@@ -2,30 +2,32 @@
<com:TContent ID="body" >
<com:TPanel GroupingText="Class Information">
-class <com:TTextBox ID="ClassName" CssClass="slTextBox"/>
-extends <com:TTextBox ID="ParentClass" CssClass="slTextBox"/>
+class
+<com:TTextBox ID="ClassName"
+ Text=<%#$this->Page->ClassDefinition->ClassName%>
+ CssClass="slTextBox"/>
+extends
+<com:TTextBox ID="ParentClass"
+ Text=<%#$this->Page->ClassDefinition->ParentClass%>
+ CssClass="slTextBox"/>
implements <com:TTextBox ID="Interfaces" CssClass="slTextBox"/>
</com:TPanel>
<com:TPanel GroupingText="Property Definitions">
<table>
<tr>
- <th>Accessibility</th>
<th>Name</th>
<th>Type</th>
<th>Default Value</th>
<th>Storage Mode</th>
+ <th>Accessibility</th>
<th>Comments</th>
<th>Actions</th>
</tr>
-<com:TRepeater ID="PropertyList">
+<com:TRepeater ID="PropertyList" ItemCommand="itemAction">
<prop:ItemTemplate>
<tr>
<td>
- <com:TCheckBox ID="IsProtected" Text="protected" Checked=<%# $this->Parent->DataItem->IsProtected %> />
- <com:TCheckBox ID="ReadOnly" Text="read-only" Checked=<%# $this->Parent->DataItem->ReadOnly %> />
- </td>
- <td>
<com:TTextBox ID="PropertyName" Text=<%# $this->Parent->DataItem->Name %> CssClass="slTextBox"/>
</td>
<td>
@@ -49,11 +51,21 @@ implements <com:TTextBox ID="Interfaces" CssClass="slTextBox"/>
</com:TDropDownList>
</td>
<td>
+ <com:TCheckBox ID="IsProtected" Text="protected" Checked=<%# $this->Parent->DataItem->IsProtected %> />
+ <com:TCheckBox ID="ReadOnly" Text="read-only" Checked=<%# $this->Parent->DataItem->ReadOnly %> />
+ </td>
+ <td>
<com:TTextBox ID="Comments" Text=<%# $this->Parent->DataItem->Comments %> CssClass="slTextBox"/>
</td>
<td>
- <com:TButton Text="Add" />
- <com:TButton Text="Remove" />
+ <com:TButton ID="AddButton"
+ Text="Add"
+ CommandName="add"
+ CommandParameter=<%# $this->Parent->ItemIndex %> />
+ <com:TButton ID="RemoveButton"
+ Text="Remove"
+ CommandName="remove"
+ CommandParameter=<%# $this->Parent->ItemIndex %> />
</td>
</tr>
</prop:ItemTemplate>
@@ -65,13 +77,18 @@ Event Definitions:
</com:TPanel>
<br/>
Comments
-(
-Author Name: <com:TTextBox ID="AuthorName" CssClass="slTextBox"/>
-Author Email: <com:TTextBox ID="AuthorEmail" CssClass="slTextBox"/>
-)
<br/>
<com:TTextBox ID="Comments" TextMode="MultiLine" Columns="80" Rows="6" />
<br/>
+Author Name
+<com:TTextBox ID="AuthorName"
+ Text=<%#$this->Page->ClassDefinition->Author%>
+ CssClass="slTextBox"/>
+Author Email
+<com:TTextBox ID="AuthorEmail"
+ Text=<%#$this->Page->ClassDefinition->Email%>
+ CssClass="slTextBox"/>
+<br/>
<com:TButton Text="Generate Code" Click="generateCode" />
<pre>
<com:TLiteral ID="SourceCode" />
diff --git a/demos/composer/protected/pages/Home.php b/demos/composer/protected/pages/Home.php
index 3c2b4d22..e0112fd7 100644
--- a/demos/composer/protected/pages/Home.php
+++ b/demos/composer/protected/pages/Home.php
@@ -20,24 +20,29 @@ class Home extends TPage
$properties[]=new PropertyDefinition;
$properties[]=new PropertyDefinition;
$properties[]=new PropertyDefinition;
- $this->PropertyList->setDataSource($properties);
+ $this->PropertyList->DataSource=$properties;
$this->dataBind();
}
}
- /*
- public function onLoad($param)
+ protected function refresh()
{
- parent::onLoad($param);
- if(!$this->IsPostBack)
+ $this->PropertyList->DataSource=$this->ClassDefinition->Properties;
+ $this->dataBind();
+ }
+
+ public function itemAction($sender,$param)
+ {
+ if($param->CommandName==='remove')
{
- $this->PropertyList->setDataSource($this->getInitialProperties());
- $this->PropertyList->dataBind();
+ $this->ClassDefinition->Properties->removeAt($param->CommandParameter);
}
- else
- $this->PropertyList->ensureChildControls();
+ else if($param->CommandName==='add')
+ {
+ $this->ClassDefinition->Properties->insert($param->CommandParameter+1,new PropertyDefinition);
+ }
+ $this->refresh();
}
- */
public function onLoad($param)
{
@@ -45,32 +50,32 @@ class Home extends TPage
//if($this->IsPostBack && $this->IsValid)
if($this->IsPostBack)
{
- $this->PropertyList->ensureChildControls();
+ $def=$this->ClassDefinition;
+ $def->reset();
+ $def->ClassName=$this->ClassName->Text;
+ $def->ParentClass=$this->ParentClass->Text;
+ $def->Interfaces=$this->Interfaces->Text;
+ $def->Comments=$this->Comments->Text;
+ $def->Author=$this->AuthorName->Text;
+ $def->Email=$this->AuthorEmail->Text;
+ foreach($this->PropertyList->Items as $item)
+ {
+ $property=new PropertyDefinition;
+ $property->Name=$item->PropertyName->Text;
+ $property->Type=$item->PropertyType->Text;
+ $property->DefaultValue=$item->DefaultValue->Text;
+ $property->ReadOnly=$item->ReadOnly->Checked;
+ $property->IsProtected=$item->IsProtected->Checked;
+ $property->Comments=$item->Comments->Text;
+ $property->Storage=$item->Storage->Text;
+ $def->Properties[]=$property;
+ }
}
}
public function generateCode($sender,$param)
{
- $def=$this->ClassDefinition;
- $def->reset();
- $def->ClassName=$this->ClassName->Text;
- $def->ParentClass=$this->ParentClass->Text;
- $def->Interfaces=$this->Interfaces->Text;
- $def->Comments=$this->Comments->Text;
- $def->Author=$this->AuthorName->Text;
- $def->Email=$this->AuthorEmail->Text;
- foreach($this->PropertyList->Items as $item)
- {
- $property=new PropertyDefinition;
- $property->Name=$item->PropertyName->Text;
- $property->Type=$item->PropertyType->Text;
- $property->DefaultValue=$item->DefaultValue->Text;
- $property->ReadOnly=$item->ReadOnly->Checked;
- $property->IsProtected=$item->IsProtected->Checked;
- $property->Comments=$item->Comments->Text;
- $property->Storage=$item->Storage->Text;
- $def->Properties[]=$property;
- }
+ $this->refresh();
$writer=Prado::createComponent('System.IO.TTextWriter');
$this->ClassDefinition->render($writer);
$this->SourceCode->Text=highlight_string($writer->flush(),true);
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);
@@ -276,6 +280,31 @@ class TRepeater extends TDataBoundControl implements INamingContainer
}
/**
+ * 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().
* You may override this function to provide your own way of data population.
@@ -307,7 +336,6 @@ class TRepeater extends TDataBoundControl implements INamingContainer
}
else
$this->setViewState('ItemCount',$itemIndex,-1);
- $this->setChildControlsCreated(true);
}
/**