在beginWidget中我们看到 yii使用挂件工厂生产了一个挂件,并执行了他的init()方法
public function beginWidget($className,$properties=array()) { $widget=$this->createWidget($className,$properties); $this->_widgetStack[]=$widget; return $widget; } public function createWidget($className,$properties=array()) { $widget=Yii::app()->getWidgetFactory()->createWidget($this,$className,$properties); $widget->init(); return $widget; }在endWidget中我们看到,执行了widget的run方法
public function endWidget($id='') { if(($widget=array_pop($this->_widgetStack))!==null) { $widget->run(); return $widget; } else throw new CException(Yii::t('yii','{controller} has an extra endWidget({id}) call in its view.', array('{controller}'=>get_class($this),'{id}'=>$id))); }如果直接使用widget方法则既调用init()方法也调用run方法,第三个参数表示是否返回值,如果为false则直接输出
public function widget($className,$properties=array(),$captureOutput=false) { if($captureOutput) { ob_start(); ob_implicit_flush(false); $widget=$this->createWidget($className,$properties); $widget->run(); return ob_get_clean(); } else { $widget=$this->createWidget($className,$properties); $widget->run(); return $widget; } }
// autoloading model and component classes 'import'=>array( 'application.models.*', 'application.components.*', 'application.widgets.*',//将widgets类导入 ),
新建widgets/DbWidget
class DbWidget extends CWidget{ public $num;//显示的用户个数 //显示最近添加的n个用户,init方法可有可无 public function init() { //初始化num值为3,如果使用挂件时没有传递num参数,则num=3 if($this->num == false){ $this->num = 3; } } public function run() { $users = $this->getUsers(); //渲染db挂件视图 $this->render('db',array( 'users'=>$users, )); } //获取最新添加的n个用户 protected function getUsers(){ return Yii::app()->db->createCommand() ->select('id,username,create_time') ->from('user') ->limit($this->num) ->order('id desc') ->queryAll(); } }在widgets目录下新建视图views/db.php
<?php if (!empty($users)): ?> <table> <tr> <th>用户ID</th> <th>用户名</th> </tr> <?php foreach ($users as $k => $user): ?> <tr> <td><?php echo $user['id']; ?></td> <td><?php echo $user['username']; ?></td> </tr> <?php endforeach; ?> </table> <?php else: ?> 没有用户信息 <?php endif; ?>
class WidgetController extends Controller{ public function actionWidget(){ $this->render('widget'); } }新建文件views/widget/widget.php
<?php $this->widget('application.widgets.DbWidget',array('num'=>5));?>在浏览器中输入 http://localhost/bootstrap/index.php/widget/widget,输出结果如图
class FormWidget extends CWidget{ public $action = ''; public $method = 'POST'; public $htmlOptions = array(); public function init() { echo CHtml::beginForm($this->action, $this->method, $this->htmlOptions); } public function run() { echo CHtml::endForm(); } //渲染一个文本框 public function textField($name,$value='',$htmlOptions=array()){ echo CHtml::textField($name, $value, $htmlOptions); } //渲染一个下拉框 public function dropDownList($name,$value='',$data=array(),$htmlOptions=array()){ echo CHtml::dropDownList($name, $value, $data, $htmlOptions); } }WidgetController中
public function actionBeginwidget(){ $this->render('begin_widget'); }view中views/begin_widget.php
<div class="form"> <?php //$form是返回的挂件对象 $form = $this->beginWidget('application.widgets.FormWidget'); ?> <div class="row"> <?php echo $form->textField('username', '用户名'); ?> </div> <div class="row"> <?php echo $form->dropDownList('city_id', 1, User::getCitys()); ?> </div> <?php echo CHtml::submitButton('提交') ?> <?php $this->endWidget(); ?> </div>