十二、挂件widget的声明与使用

在视图active_form中我们可以看到,在渲染表单的时候,调用了控制器的beginWidget方法,这个方法表示初始化一个挂件,那么挂件是什么,怎么使用列
 
挂件都继承自基类CWidget
一个微件是自包含的组件,它可以基于模型数据显示相应的内容。我们可以将其视为一个嵌入到控制器管理的视图中的微控制器。
 
 
挂件的使用方式有两种,一种是使用$controller->widget();一种是使用$controller->beginWidget()和$controller->endWidget()组合使用
我们进入Controller里面分别看一下这两种方法

在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;
    }
}
下面我分别就这两种挂件来举个例子
一.widget的使用
首先在应用基础目录protected下新建一个widgets的文件夹
然后在config配置目录下修改main.php
// autoloading model and component classes
    'import'=>array(
        'application.models.*',
        'application.components.*',
        'application.widgets.*',//将widgets类导入
    ),
做一个展示最近新添加的n用户的挂件

新建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; ?>
挂件的引用
新建文件controllers/WidgetController
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,输出结果如图

注:挂件的视图层中$this 指向的是挂件对象,如果想使用当前controller对象,需要使用Yii::app()->controller
 
二.beginWidget和endWidget的使用
比如我们做一个表单挂件
创建挂件 widgets/FormWidget.php
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>

转载于:https://my.oschina.net/lonxom/blog/168246

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值