prince
(Ice42)
1
我修改了demo blog的controller post,对action index使用缓存。这样就要在view main里面对UserMenu使用renderDynamic方法了。但是我没有对action admin使用缓存。所以访问action admin的时候renderDynamic就不能把<###dynamic-0###>替换为UserMenu的内容了,而是替换成了其他的缓存的内容。
我又试了一下,把所有的缓存都关了。这时候action admin的<###dynamic-0###>就不被替换成任何内容而直接显示出来。
yii对renderDynamic的处理是否应该修改一下,当找不到它的缓存内容的时候应该直接输出回调函数返回的内容(好像被保存在$this->_dynamicOutput里面了)或者抛出错误,而不应该把<###dynamic-0###>替换成之前其他的缓存内容吧?
prince
(Ice42)
2
调试了很长时间,发现是<###dynamic-$n###>这里的这个$n引起的。$n=count($this->_dynamicOutput);这个视图用到了两次renderDynamic,照说$n应该第一次等于0,第二次等于1了,也就是生成了之前一次<###dynamic-0###>,而UserMenu应该是<###dynamic-1###>。但实际上UserMenu还是<###dynamic-0###>。
这两个renderDynamic分别在layouts column2.php和layouts main.php里面,我把两个renderDynamic都放在layouts main.php里面就没有这个问题了。
能否给renderDynamic增加一个参数,允许手动指定<###dynamic-$n###>的这个$n。这样就可以避免出现这个问题了。
qiang
(Qiang Xue)
4
我刚刚添加了一个$key参数到renderDynamic()。你能帮忙测试一下么?谢谢。
prince
(Ice42)
5
你那种写法有问题。我改了一下:
public function renderDynamic($callback,$key=null)
{
$params=func_get_args();
array_shift($params);
if($key===null || !is_numeric($key))
{
$n=count($this->_dynamicOutput);
}
else
{
$n=$key;
array_shift($params);
}
echo "<###dynamic-$n###>";
$this->renderDynamicInternal($callback,$params,$n);
}
public function renderDynamicInternal($callback,$params,$key)
{
$this->recordCachingAction('','renderDynamicInternal',array($callback,$params,$key));
if(is_string($callback) && method_exists($this,$callback))
$callback=array($this,$callback);
$this->_dynamicOutput[$key]=call_user_func_array($callback,$params);
}
但是还是有问题。我指定的$key是110,它生成的缓存ID是<###dynamic-110###>,但它并没有被替换成UserMenu的内容。而是输出<###dynamic-110###>。我调试发现 processDynamicOutput($output) 的$output始终是空值。不知道是为什么? 
qiang
(Qiang Xue)
6
刚check in的代码的确有问题,忘记了renderDynamic接受动态参数了。
你能提交一个ticket么?最好能提供一个简单的例子来重现这个问题。多谢了。
prince
(Ice42)
7
我刚才尝试写一个简单例子,但没能重现这个问题。在yii的demo blog里面就能重现。还没搞清楚是什么原因。等我写出一个重现这个问题的例子再提交ticket 
prince
(Ice42)
8
Qiang,我发现我上面的判断错了。用两个demo blog改的程序对比。发现一个正常,另外一个的renderDynamic就出问题了。两个的区别仅在layouts column2.php中的一处。
正常的:
<?php $this->beginContent('/layouts/main'); ?>
<div class="container">
<div class="span-18">
<div id="content">
<?php echo $content; ?>
</div><!-- content -->
</div>
<div class="span-6 last">
<div id="sidebar">
<?php $this->renderDynamic('widget', 'UserMenu', array('id'=>'user'), true); ?>
<?php $this->widget('TagCloud', array(
'maxTags'=>Yii::app()->params['tagCloudCount'],
)); ?>
<?php $this->widget('RecentComments', array(
'maxComments'=>Yii::app()->params['recentCommentCount'],
)); ?>
</div><!-- sidebar -->
</div>
</div>
<?php $this->endContent(); ?>
有问题的:
<?php $this->beginContent('/layouts/main'); ?>
<div class="container">
<div class="span-18">
<div id="content">
<?php echo $content; ?>
</div><!-- content -->
</div>
<div class="span-6 last">
<div id="sidebar">
<?php $this->renderDynamic('widget', 'UserMenu', array('id'=>'user'), true);//$this->widget('UserMenu'); ?>
<?php if($this->beginCache('tagCloud', array('duration'=>99999999, 'dependency'=>array(
'class'=>'system.caching.dependencies.CDbCacheDependency',
'sql'=>'SELECT MAX(id) FROM '.Yii::app()->db->tablePrefix.'tag')))) { ?>
<?php $this->widget('TagCloud', array(
'maxTags'=>Yii::app()->params['tagCloudCount'],
)); ?>
<?php $this->endCache(); } ?>
<?php $this->widget('RecentComments', array(
'maxComments'=>Yii::app()->params['recentCommentCount'],
)); ?>
</div><!-- sidebar -->
</div>
</div>
<?php $this->endContent(); ?>
就多了一个,对Tags的缓存。麻烦Qiang解答一下,这个地方有什么问题吗?还需不需要提交ticket?
prince
(Ice42)
9
我刚才又写了一个简单的例子来重现了这个问题。觉得这个地方确实有问题,还是有必要提交一个ticket.
ticket已经提交.Issues 1130
例子也附在下面了,但例子里面没包含yii framework的源码,你要在index里面修改一下包含yii framework的路径再运行。