在yii框架演示中,有一个博客演示。在这个博客演示中,Post控制器有两个不同的操作:索引和视图。
/**
* Lists all models.
*/
public function actionIndex()
{
$criteria=new CDbCriteria(array(
'condition'=>'status='.Post::STATUS_PUBLISHED,
'order'=>'update_time DESC',
'with'=>'commentCount',
));
if(isset($_GET['tag']))
$criteria->addSearchCondition('tags',$_GET['tag']);
$dataProvider=new CActiveDataProvider('Post', array(
'pagination'=>array(
'pageSize'=>Yii::app()->params['postsPerPage'],
),
'criteria'=>$criteria,
));
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}
/**
* Displays a particular model.
*/
public function actionView()
{
$post=$this->loadModel();
$comment=$this->newComment($post);
$this->render('view',array(
'model'=>$post,
'comment'=>$comment,
));
}
和索引视图是:
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'template'=>"{items}\n{pager}",
)); ?>
并且查看视图是:
<?php $this->renderPartial('_view', array(
'data'=>$model,
)); ?>
但索引和视图都使用_view:
<div class="author">
posted by <?php echo $data->author->username . ' on ' . date('F j, Y',$data->create_time); ?>
</div>
<div class="content">
<?php
$this->beginWidget('CMarkdown', array('purifyOutput'=>true));
echo $data->content;
$this->endWidget();
?>
</div>
这是我的问题:我可以理解视图分配'data'=&gt; $ model,所以在_view中,$ data是有效的。在索引操作中,应用了小部件clistview,但我无法理解在哪里设置$ data变量?我知道$ data显示当前帖子(来自dataprovider)。我只是无法弄清楚yii是如何做到这一点的? 谢谢你的帮助。
答案 0 :(得分:0)
上面的代码首先为Post ActiveRecord类创建一个数据提供程序。然后,它使用CListView显示数据提供程序返回的每个数据项。显示通过名为'_post'的部分视图完成。对于每个数据项,此局部视图将呈现一次。在视图中,可以通过变量$ data访问当前数据项。
使用CListView的itemView属性,该属性用于呈现每个数据项。此属性值将作为第一个参数传递给CController属性renderpartial以呈现每个数据项。
public string renderPartial(string $view, array $data=NULL, boolean $return=false, boolean $processOutput=false)
public function renderPartial($view,$data=null,$return=false,$processOutput=false)
{
if(($viewFile=$this->getViewFile($view))!==false)
{
$output=$this->renderFile($viewFile,$data,true);
if($processOutput)
$output=$this->processOutput($output);
if($return)
return $output;
else
echo $output;
}
else
throw new CException(Yii::t('yii','{controller} cannot find the requested view "{view}".',
array('{controller}'=>get_class($this), '{view}'=>$view)));
}
呈现视图。
如果$ data是一个关联数组,它将被提取为PHP变量并可供脚本使用。命名视图引用PHP脚本。脚本通过getViewFile解析在renderPartial方法中使用getViewFile的脚本为如下所示
public function getViewFile($viewName)
{
if(($theme=Yii::app()->getTheme())!==null && ($viewFile=$theme->getViewFile($this,$viewName))!==false)
return $viewFile;
$moduleViewPath=$basePath=Yii::app()->getViewPath();
if(($module=$this->getModule())!==null)
$moduleViewPath=$module->getViewPath();
return $this->resolveViewFile($viewName,$this->getViewPath(),$basePath,$moduleViewPath);
}
根据给定的视图名称查找视图文件。
renderItems是CBaseListView ClassFile
中定义的抽象方法/**
* Renders the data items for the view.
* Each item is corresponding to a single data model instance.
* Child classes should override this method to provide the actual item rendering logic.
*/
abstract public function renderItems();
此方法由ClistView类覆盖
答案 1 :(得分:0)
CListView
小部件循环通过$dataProvider
,对于每个项目,它都会执行类似的操作:
$this->renderPartial($itemView, array(
'data'=>$model,
));
其中$itemView
是CListView
config。
就是这样。
修改:澄清CListView
iterates over dataprovider items:CListView::renderItems
中定义的内容,简而言之,最重要的部分是:
// Get dataprovider data as array
$data=$this->dataProvider->getData();
...
// Get viewfile
$viewFile=$owner->getViewFile($this->itemView);
...
// Loop thru $data items
foreach($data as $i=>$item)
{
...
// Here data is assigned from dataprovider item
$data['data']=$item;
...
// Render view file
$owner->renderFile($viewFile,$data);
}