MikeHaertl/xcrudcontroller

xcrudcontroller 是一个 Yii 基础类,用于快速构建定制的 CRUD 接口。

1.0.1 2013-02-20 18:03 UTC

This package is auto-updated.

Last update: 2024-08-24 04:07:50 UTC


README

快速构建定制的 CRUD 接口的基类。

特性

  • 创建、列表、查看、编辑和删除操作。遵循DRY原则,不要在所有控制器中重复相同的CRUD逻辑。
  • 强大的过滤模式。在列表中使用专门的过滤表单来构建便捷的搜索界面。
  • URL创建助手。在编辑/查看记录后,将用户带回相同的列表页面。

快速入门

1 简单控制器

要开始,您只需提供要为其实现 CRUD 的 ActiveRecord 类的名称。

<?php
Yii::import('ext.xcrudcontroller.XCrudController');
class UserController extends XCrudController
{
    public $modelName = 'User';
}

2 创建视图文件

您必须提供 listeditdetail 视图。

注意:标记非常简洁。在实际项目中,您当然会适当地设计这些元素。您也可以从 Gii 生成的 CRUD 模板开始。但您需要稍作调整和修改。

2.1 列表视图

list 视图包含过滤表单并通过 _items 渲染实际项目的部分视图。

protected/views/user/list.php

<?php $model = $this->filterModel; ?>

<div>
    <h2>Search users</h2>
    <?php echo CHtml::beginForm(array('list'),'get'); ?>
        <label>
            Username
            <?php echo CHtml::activeTextField($model, 'username'); ?>
        </label>
        <label>
            Email
            <?php echo CHtml::activeTextField($model, 'email'); ?>
        </label>
        <?php echo CHtml::submitButton('Search'); ?>
    <?php echo CHtml::endForm(); ?>
</div>

<?php $this->renderPartial('_items'); ?>

注意:在实际生活中,您的过滤表单通常会提供更多搜索选项。您最好通过专门的过滤表单来实现这一点。下面将详细介绍。

protected/views/user/_items.php

<?php $this->widget('zii.widgets.grid.CGridView',array(
    'dataProvider' => $this->filterModel->search(),
    'columns' => array(
        'id',
        array(
            'name'  => 'Username',
            'value' => 'CHtml::link($data->username, Yii::app()->controller->createItemUrl($data, "view"))',
            'type'  => 'raw',
        ),
        'email',
        array(
            'class'=>'CButtonColumn',
            'template'=>'{update} {delete}',
            'buttons'=>array(
                'update'=>array(
                    'url'=>'Yii::app()->controller->createItemUrl($data,"edit")'
                ),
            ),
        ),
    )
)); ?>

注意,查看和编辑项目的链接是通过 createItemUrl() 构建的。这会将当前列表页面的URL作为URL参数添加,因此很容易链接回此搜索结果页面。

2.2 创建/编辑表单

protected/views/user/form.php

<?php $model = $this->model; ?>

<h1><?php echo $model->isNewRecord ? 'Add new user' : 'Edit user' ?></h1>

<?php $form=$this->beginWidget('CActiveForm',array(
    'id' => 'user-form',
));?>
    <div>
        <?php echo $form->label($model, 'username'); ?>
        <?php echo $form->textField($model, 'username'); ?>
        <?php echo $form->error($model, 'username'); ?>
    </div>
    <div>
        <?php echo $form->label($model, 'email'); ?>
        <?php echo $form->textField($model, 'email'); ?>
        <?php echo $form->error($model, 'email'); ?>
    </div>
    <div>
        <?php echo $form->label($model, 'password'); ?>
        <?php echo $form->textField($model, 'password'); ?>
        <?php echo $form->error($model, 'password'); ?>
    </div>

    <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save') ?>
    <?php echo CHtml::link('Cancel', $this->returnUrl); ?>

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

注意:如果您想使用 CActiveForm 进行AJAX验证,表单名称必须为 strtolower($this->modelName).'-form'

2.3 详细视图

protected/views/user/form.php

<?php $model = $this->model; ?>

<div>
    <?php $this->widget('zii.widgets.CDetailView', array(
        'data' => $model,
    )); ?>
</div>

<?php echo CHtml::link('Back', $this->returnUrl); ?>

配置

视图

如上所述,控制器需要提供4个视图文件

  • list:包含过滤表单并渲染 _items 部分视图
  • _items:渲染项目(例如,使用 CListView/CGridView
  • form:渲染创建/编辑表单
  • detail:渲染详细视图

可以在 $listView$listPartial$formView$detailView 属性中配置视图名称。

视图使用拉取机制来获取其数据

  • $this->model:返回 formdetail 视图当前模型
  • $this->filterModel:返回 list_items 视图的过滤模型。项目的数据提供程序可通过 search() 方法获取。
  • $this->returnUrl:包含将用户带回搜索结果页面的URL。这在 editview 页面上很有用。

记录创建或更新后,会设置带有键 $modelName-created$modelName-updated 的闪存消息。您可以使用此消息在保存记录后显示成功消息。

注意:您可以控制创建新记录后要显示的页面。默认情况下,这将是一个列表页面(带有重置的过滤器)。您还可以显示新记录的详细视图或停留在编辑页面上。因此,您必须创建如下所示的 "添加" 链接

CHtml::link('添加用户', array('edit', $this->returnVar=>'view'));

您也可以使用'edit'代替'view',以便跳转到新创建记录的编辑表单。

场景

您可以配置几个场景,这些场景设置在 $model$filterModel 上,用于特定操作。

  • $createScenario : 在创建新记录时设置。默认是 create
  • $updateScenario : 在更新记录时设置。默认是 update
  • $filterScenario : 在分配搜索参数时设置在过滤器模型上。默认是 filter

其他选项

如果您不想提供所有操作,您可以通过 $crudActions 禁用其中一些。默认情况下,这是 `array('edit', 'list', 'view', 'delete')`。

返回URL参数的URL参数名称通过 $returnVar 设置,默认为 returnUrl

高级技巧

使用过滤器模型

在最简单的情况下,过滤器模型是Gii创建的ActiveRecord。但如果你想保持代码的整洁,我建议为所有的过滤器关注点使用单独的模型文件。这样做的好处是您不再用与搜索相关的代码来弄乱您的ActiveRecords,并且可以专注于这里的搜索逻辑。

<?php
class UserFilter extends CFormModel
{
    public $username;
    public $email;

    // You can add many more attributes here, to offer convenient search options
    public $ageMin;
    public $ageMax;

    // All these attributes must be declared as 'safe'
    public function rules()
    {
        return array(
            array('username,email', 'safe'),
        );
    }

    // As usual, build the search criteria from the current attribute values.
    // In real life you may even use a dedicated search engine like Solr -
    // as long as it returns a valid data provider everything will still work.
    // All attribute values are translated into query conditions.
    public function search()
    {
        $criteria = new CDbCriteria;

        if(!empty($this->username))
            $criteria->compare('username', $this->name);

        if(!empty($this->email))
            $criteria->compare('email', $this->city);

        if(!empty($this->ageMin))
            $criteria->addCondition('birthday < SUBDATE(NOW(), INTERVAL '.(int)$this->ageMin.' YEAR)');

        if(!empty($this->ageMax))
            $criteria->addCondition('birthday > SUBDATE(NOW(), INTERVAL '.(int)$this->ageMax.' YEAR)');

        return new CActiveDataProvider('User', array(
            'criteria' => $criteria,

            // Add more options as required, e.g. for sorting
        ));
    }
}

在控制器中,您必须在 $filterModelName 中配置此模型。

<?php
Yii::import('ext.xcrudcontroller.XCrudController');
class UserController extends XCrudController
{
    public $modelName = 'User';
    public $filterMlodelName = 'UserFilter';
}

如何为您的搜索结果获得更美观的URL

搜索结果页面的URL参数看起来像这样

...&User[username]=test&User[email]=@example.com

这看起来不是很美观。如果像Google或其他搜索引擎一样使用更易读的搜索参数会更好。

...&username=test&email=@example.com

实现这一点非常简单。您需要在控制器中重写 assignFilterModelAttributes() 方法,如下所示

<?php
    protected function assignFilterModelAttributes($model)
    {
        $model->attributes = $_GET;
    }

在这种情况下这样做是安全的:我们只有搜索表单参数在 $_GET 中,也许还有分页和排序选项。但只要它们不与您的搜索模型属性冲突,一切仍然正常。

但您还必须稍微修改一下过滤器表单,因为默认情况下,Yii会创建像 User[username] 这样的表单元素名称,而我们希望它们现在是仅 username

    <?php echo CHtml::beginForm(array('list'),'get'); ?>
        <label>
            Username
            <?php echo CHtml::textField('username', $model->username); ?>
        </label>
        ...