2013-06-26 41 views
0

在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> 

這裏是我的問題:我可以理解視圖分配'數據' => $ model,所以在_view中,$ data是有效的。在索引操作中,應用了部件clistview,但我無法理解$ data變量的設置位置?我知道$ data顯示了當前的帖子(來自dataprovider)。我只是無法弄清楚yii是怎麼做到的? 感謝您的幫助。

回答

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中類已覆蓋

+0

謝謝您的回答。所以我可以看到yii會將關聯數組提取到當前腳本。我看到一個名爲renderItems的CListView方法,這個方法是在做循環渲染工作嗎?如果是這樣,renderItems被調用到什麼地方? – rereadyou

+0

更新了答案 – Ninad

+0

我只是不知道哪種方法會實際上做循環工作。我在框架目錄中找不到任何稱爲此renderItems函數的方法,並且它的所有子目錄(如果此renderItems函數循環通過$ dataprovider) – rereadyou

0

CListView部件環路直通$dataProvider,併爲每個項目它類似的東西:

$this->renderPartial($itemView, array(
    'data'=>$model, 
)); 

其中$itemViewCListView配置中的查看文件集。

就是這樣。

編輯:要澄清的是如何CListViewiterates 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); 
} 
+0

感謝您的回答。現在我知道了,yii將提取作爲第二個參數傳遞給當前腳本的變量數組,並且CListView小部件通過$ dataProvider循環。我查看了CListView src,但仍然不知道哪個方法會執行循環$ dataProvider的工作,請給我一個提示? – rereadyou

+0

@rereadyou,我更新了答案 – 2013-06-29 09:50:26

+0

是的,就是這樣。感謝您的回答。這個renderItems方法似乎做循環工作。我最後的困惑是:這個renderItems被調用的地方在哪裏?我查看通過yii src文件,並找到沒有來電者。 – rereadyou

相關問題