在使用clistview小部件时,如何从dataprovider中提取$ data?

时间:2013-06-26 12:13:39

标签: php yii

在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是如何做到这一点的? 谢谢你的帮助。

2 个答案:

答案 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,
));

其中$itemViewCListView config。

中设置的视图文件

就是这样。

修改:澄清CListView iterates over dataprovider itemsCListView::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);
}