directory search
阅读前篇 简介 Yii 是什么 从 Yii 1.1 升级 入门 安装 Yii 运行应用 第一次问候 使用Forms 数据库应用 使用 Gii 生成代码 进阶 应用结构 概述 入口脚本 应用(Applications) 应用组件(Application Components) 控制器(Controllers) 模型(Models) 视图(views) 模块(Modules) 过滤器(Filters) 小部件(Widgets) 前端资源(Assets) 扩展(Extensions) 请求处理 运行概述 启动引导(Bootstrapping) 路由和创建URL 请求(Requests) 响应(Responses) Sessions 和 Cookies 错误处理(Handling Errors) 日志(Logging) 关键概念 组件(Component) 属性(Property) 事件(Events) 行为(Behaviors) 配置(Configurations) 别名(Aliases) 类自动加载(Autoloading) 服务定位器(Service Locator) 依赖注入容器(Dependency Injection Container) 配合数据库工作 数据库访问 (Data Access Objects) 查询生成器(Query Builder) 活动记录(Active Record) 数据库迁移(Migrations) Sphinx Redis MongoDB Elasticsearch 接收用户数据 创建表单(Creating Forms) 输入验证(Validating Input) 文件上传(Uploading Files) 收集列表输入(Collecting Tabular Input) 多模型的复合表单(Getting Data for Multiple Models) 显示数据 格式化输出数据(Data Formatting) 分页(Pagination) 排序(Sorting) 数据提供器(Data Providers) 数据小部件(Data Widgets) 客户端脚本使用(Working with Client Scripts) 主题(Theming) 安全 认证(Authentication) 授权(Authorization) 处理密码(Working with Passwords) 客户端认证(Auth Clients) 最佳安全实践(Best Practices) 缓存 概述 数据缓存 片段缓存 页面缓存 HTTP 缓存 RESTfull Web服务 快速入门(Quick Start) 资源(Resources) 控制器(Controllers) 路由(Routing) 格式化响应(Response Formatting) 授权认证(Authentication) 速率限制(Rate Limiting) 版本(Versioning) 错误处理(Error Handling) 开发工具 调试工具栏和调试器 使用Gii生成代码 生成API文档 测试 概述(Overview) 配置测试环境(Testing environment setup) 单元测试(Unit Tests) 功能测试(Function Tests) 验收测试(Acceptance Tests) 测试夹具(Fixtures) 高级专题 高级应用模板 创建自定义应用程序结构 控制台命令 核心验证器(Core Validators) 国际化 收发邮件 性能优化 共享主机环境 模板引擎 集成第三方代码 小部件 Bootstrap 小部件 Jquery UI 助手类 概述 Array 助手(ArrayHelper) Html 助手(Html) Url 助手(Url)
characters

小部件

小部件

小部件是在 视图 中使用的可重用单元,使用面向对象方式创建复杂和可配置用户界面单元。 例如,日期选择器小部件可生成一个精致的允许用户选择日期的日期选择器, 你只需要在视图中插入如下代码:

<?phpuse yii\jui\DatePicker;
?><?= DatePicker::widget(['name' => 'date']) ?>

Yii提供许多优秀的小部件,比如yii\widgets\ActiveForm, [yii\widgets\Menu|menu]], jQuery UI widgets, Twitter Bootstrap widgets。 接下来介绍小部件的基本知识,如果你想了解某个小部件请参考对应的类API文档。

使用小部件

小部件基本上在views中使用,在视图中可调用 yii\base\Widget::widget() 方法使用小部件。 该方法使用 配置 数组初始化小部件并返回小部件渲染后的结果。 例如如下代码插入一个日期选择器小部件,它配置为使用俄罗斯语,输入框内容为$modelfrom_date属性值。

<?phpuse yii\jui\DatePicker;
?><?= DatePicker::widget([
    'model' => $model,
    'attribute' => 'from_date',
    'language' => 'ru',
    'clientOptions' => [
        'dateFormat' => 'yy-mm-dd',
    ],
]) ?>

一些小部件可在yii\base\Widget::begin() 和 yii\base\Widget::end() 调用中使用数据内容。Some widgets can take a block of content which should be enclosed between the invocation of 例如如下代码使用yii\widgets\ActiveForm小部件生成一个登录表单, 小部件会在begin() 和0 end()执行处分别生成<form>的开始标签和结束标签,中间的任何代码也会被渲染。

<?phpuse yii\widgets\ActiveForm;
use yii\helpers\Html;
?>

<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>

    <?= $form->field($model, 'username') ?>

    <?= $form->field($model, 'password')->passwordInput() ?>

    <div class="form-group">
        <?= Html::submitButton('Login') ?>
    </div>

<?php ActiveForm::end(); ?>

注意和调用 yii\base\Widget::widget() 返回渲染结果不同, 调用 yii\base\Widget::begin() 方法返回一个可组建小部件内容的小部件实例。

创建小部件

Creating Widgets

继承 yii\base\Widget 类并覆盖 yii\base\Widget::init() 和/或 yii\base\Widget::run() 方法可创建小部件。通常init() 方法处理小部件属性, run() 方法包含小部件生成渲染结果的代码。 渲染结果可在run()方法中直接"echoed"输出或以字符串返回。

如下代码中HelloWidget编码并显示赋给message 属性的值, 如果属性没有被赋值,默认会显示"Hello World"。

namespace app\components;

use yii\base\Widget;
use yii\helpers\Html;

class HelloWidget extends Widget{
    public $message;

    public function init()
    {
        parent::init();
        if ($this->message === null) {
            $this->message = 'Hello World';
        }
    }

    public function run()
    {
        return Html::encode($this->message);
    }
}

使用这个小部件只需在视图中简单使用如下代码:

<?phpuse app\components\HelloWidget;
?><?= HelloWidget::widget(['message' => 'Good morning']) ?>

以下是另一种可在begin() 和 end()调用中使用的HelloWidget,HTML编码内容然后显示。

namespace app\components;

use yii\base\Widget;
use yii\helpers\Html;

class HelloWidget extends Widget{
    public function init()
    {
        parent::init();
        ob_start();
    }

    public function run()
    {
        $content = ob_get_clean();
        return Html::encode($content);
    }
}

如上所示,PHP输出缓冲在init()启动,所有在init() 和 run()方法之间的输出内容都会被获取,并在run()处理和返回。

补充: 当你调用 yii\base\Widget::begin() 时会创建一个新的小部件实例并在构造结束时调用init()方法, 在end()时会调用run()方法并输出返回结果。

如下代码显示如何使用这种 HelloWidget:

<?phpuse app\components\HelloWidget;
?><?php HelloWidget::begin(); ?>

    content that may contain <tag>'s

<?php HelloWidget::end(); ?>

有时小部件需要渲染很多内容,一种更好的办法是将内容放入一个视图文件, 然后调用yii\base\Widget::render()方法渲染该视图文件,例如:

public function run(){
    return $this->render('hello');
}

小部件的视图文件默认存储在WidgetPath/views目录,WidgetPath代表小部件类文件所在的目录。 假如上述示例小部件类文件在@app/components下,会渲染@app/components/views/hello.php视图文件。 You may override 可以覆盖yii\base\Widget::getViewPath()方法自定义视图文件所在路径。

最佳实践

小部件是面向对象方式来重用视图代码。

创建小部件时仍需要遵循MVC模式,通常逻辑代码在小部件类,展示内容在视图中。

小部件设计时应是独立的,也就是说使用一个小部件时候,可以直接丢弃它而不需要额外的处理。 但是当小部件需要外部资源如CSS, JavaScript, 图片等会比较棘手, 幸运的时候Yii提供 资源包 来解决这个问题。

当一个小部件只包含视图代码,它和视图很相似, 实际上,在这种情况下,唯一的区别是小部件是可以重用类,视图只是应用中使用的普通PHP脚本。
Previous article: Next article: