首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Yii Widget 元件開發完整指南與實戰範例

     編輯:PHP 綜合知識

Widget 簡介

Yii 的 CWidget 是可重用的展示層元件,封裝了視圖渲染邏輯與資料處理,支援 `beginWidget`/`endWidget` 成對調用捕獲內容區塊。本文詳細說明 Widget 的建立、配置與視圖渲染完整流程。

目錄結構

protected/
└── widgets/
    └── test/
        ├── TestWidget.php      # Widget 類別
        └── views/
            └── test.php        # Widget 視圖檔

Widget 類別實作

<?php
/**
 * Test Widget 元件
 */
class TestWidget extends CWidget
{
    public $title = '預設標題';  // 可從外部傳入的屬性
    public $items = array();     // 資料陣列
    
    /**
     * 初始化:beginWidget() 時執行
     * 適用:資料查詢、參數驗證、資源註冊
     */
    public function init()
    {
        parent::init();
        
        // 範例:查詢最新文章
        if (empty($this->items)) {
            $this->items = Post::model()->recent()->limit(5)->findAll();
        }
        
        // 註冊 CSS/JS
        $this->registerAssets();
    }
    
    /**
     * 執行渲染:endWidget() 時執行
     * 適用:視圖渲染、輸出 HTML
     */
    public function run()
    {
        // 渲染 Widget 視圖,傳遞變數
        $this->render('test', array(
            'title' => $this->title,
            'items' => $this->items,
            'widget' => $this,  // 傳遞自身引用
        ));
    }
    
    protected function registerAssets()
    {
        $assets = Yii::app()->assetManager->publish(
            dirname(__FILE__) . '/assets'
        );
        Yii::app()->clientScript->registerCssFile($assets . '/widget.css');
    }
}

Widget 視圖檔

protected/widgets/test/views/test.php

<div class="widget-test">
    <h3><?php echo CHtml::encode($title); ?></h3>
    <ul>
    <?php foreach ($items as $item): ?>
        <li>
            <?php echo CHtml::link(CHtml::encode($item->title), $item->url); ?>
            <span class="time"><?php echo date('Y-m-d', $item->create_time); ?></span>
        </li>
    <?php endforeach; ?>
    </ul>
</div>

視圖中調用方式

方式一:成對調用(捕獲內容區塊)

<?php
$this->beginWidget('application.widgets.test.TestWidget', array(
    'title' => '最新文章',
    'items' => $customItems,
));
?>

<!-- 這裡的內容可在 Widget 中透過 $this->getContent() 獲取 -->
<p>自定義內容區塊...</p>

<?php $this->endWidget(); ?>

方式二:單次調用(直接渲染)

<?php
$this->widget('application.widgets.test.TestWidget', array(
    'title' => '熱門標籤',
    'items' => Tag::model()->popular()->limit(10)->findAll(),
));
?>

方式三:控制器中渲染

// 控制器 Action 中
$this->render('index', array(
    'widgetContent' => $this->renderPartial('//widgets/test', array(
        'title' => '側邊欄',
    ), true),  // true = 返回字串而非直接輸出
));

進階應用:可配置的通用列表 Widget

class ListWidget extends CWidget
{
    public $modelClass = 'Post';
    public $criteria = array();
    public $viewFile = '_list';
    public $htmlOptions = array('class' => 'widget-list');
    
    public function run()
    {
        $model = CActiveRecord::model($this->modelClass);
        $dataProvider = new CActiveDataProvider($model, array(
            'criteria' => $this->criteria,
        ));
        
        $this->render($this->viewFile, array(
            'dataProvider' => $dataProvider,
            'htmlOptions' => $this->htmlOptions,
        ));
    }
}

使用範例

<?php $this->widget('application.widgets.ListWidget', array(
    'modelClass' => 'Product',
    'criteria' => array(
        'condition' => 'status=1 AND category_id=:cat',
        'params' => array(':cat' => 5),
        'order' => 'create_time DESC',
        'limit' => 8,
    ),
    'viewFile' => 'product_grid',
)); ?>

最佳實踐建議

  • 單一職責:每個 Widget 只負責一個獨立展示功能
  • 資料與視圖分離:`init()` 處理資料,`run()` 負責渲染
  • 資源管理:使用 `CAssetManager` 發布 CSS/JS/圖片
  • 快取支援:在 `run()` 中加入片段快取 `beginCache()`/`endCache()`
  • 命名空間:建議使用 `application.widgets.模組名.Widget名` 路徑

Widget 是 Yii 視圖層複用的核心機制,善用它可大幅減少重複代碼,提升開發效率與維護性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved