Yii2用Gii自動生成Module+Model+CRUD

1. 開啓gii模塊


common/config/main-local.php加入下面代碼php

return [
    'modules' => [
        'gii'   => [
            'class' => 'yii\gii\Module',
            'allowedIPs' => ['::1','127.0.0.1'], //只容許本地訪問gii
            'generators'=> [
            /*從新定義gii model & crud的生成模板*/
            'module'=> [
                'class' => 'yii\gii\generators\module\Generator',
                'templates'=> [
                    'backend'=>'@common/gii/generators/module/default'
                ]
            ],
            'model'=> [
                'class' => 'yii\gii\generators\model\Generator',
                'baseClass'=> 'base\BaseActiveRecord',
                'ns'=> 'common\models',
                'templates'=> [
                    'common'=>'@common/gii/generators/model/default',
                    'backend'=>'@common/gii/generators/model/backend'
                ]
            ],
            'crud'=> [
                'class' => 'yii\gii\generators\crud\Generator',
                'templates'=> [
                    'backend'=>'@common/gii/generators/crud/default'
                ],
                    'baseControllerClass' => 'BaseBackendController',
                    'messageCategory'=> 'backend'
                ]
            ]
        ]
    ]
];

2. 訪問gii


URL:http://localhost/項目目錄/backend/index.php/giisql

gii界面

3. 生成模塊


圖片描述

之後臺模塊爲示例:
Module Class 填寫要生成module的路徑
Module ID 填寫模塊名
Code Template 選擇咱們自定義好的Module生成模板數據庫

若是生成成功會顯示以下:app

圖片描述

4. 生成公共模型


圖片描述

生成一個公共模型,方便不一樣入口應用複用和繼承。yii

生成成功會顯示以下:ide

圖片描述

5. 生成後臺私有模型


生成後臺私有模型,並繼承公共模型,在該類中實現後臺私有的方法。函數

圖片描述

生成成功會顯示以下:ui

clipboard.png

6. 生成CRUD操做和視圖


clipboard.png

去掉用不到的視圖文件this

clipboard.png

生成成功會顯示以下:spa

clipboard.png

7. URL訪問默認控制器


crud組件common\gii\Crud來實現基礎的action

Crud裏的index方法已經作好了分頁處理。
index視圖:backend/modules/test/views/default/index.php
如非必要,不要直接書寫原生的SQL

joinWidth方法來關聯表,須要在Test類定義好表關聯。(注意joinWith裏的大小寫)
關於關聯表的具體用法請參考:
http://www.yiichina.com/doc/guide/2.0/db-active-record

backend/modules/test/models/Test.php

public function getHabitusArticle()
    {
        /**
        * 第一個參數爲要關聯的字表模型類名稱,
        *第二個參數指定 經過子表的 customer_id 去關聯主表的 id 字段
        */
        return $this->hasMany(HabitusArticle::className(), ['hid' => 'hid']);
    }

backend/modules/test/controllers/DefaultController.php

/**
    * 
    * 查詢
    */
    public function actionIndex()
    {
        $model = $this->findModel();
        $search_model = new TestSearch;
        $query = $model::find()->select(['*'])->joinWith('habitusArticle')->orderBy('`test`.`hid` asc');
        $query = $search_model->search($query);
        //$query;
        //若是要打印SQL
        //$query = $query->createCommand();
        //echo $query->sql;die;
        echo Yii::$app->crud->index($query, ['model'=> $model]);
    }

獲得的SQL:

SELECT * FROM `test` LEFT JOIN `habitus_article` ON `test`.`hid` = `habitus_article`.`hid` ORDER BY `hid`

clipboard.png

8. 字段顯示值的格式化


先要在modles裏定義字段的別名。

backend/modules/test/models/Test.php

/**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'hid' => 'Hid',
            'name' => '名稱',//定義別名
            'remark' => '描述',//定義別名
            'percent' => 'Percent',//....
            'hearttrait' => 'Hearttrait',
            'common' => 'Common',
            'nacs' => 'Nacs',
            'attack' => 'Attack',
            'listorder' => 'Listorder',
            'datetime' => 'Datetime',
            'status' => 'Status',
            'created_by' => 'Created By',
            'updated_by' => 'Updated By',
        ];
    }

對於字段值重寫,只需定義好Model裏的attributeFormats()方法來實現字段格式化輸出。(非Yii2方法)
以下:
訪問index方法時,datetime字段會被格式爲"Y-m-d H:i:s"格式,
訪問xls方法時,datetime字段會被格式爲"Y年m月d日"格式,
匿名函數中的$value表示字段原始值,$data表示select所列出的全部字段值

backend/modules/test/models/Test.php

/**
     * 字段格式化
    
     */
    public function attributeFormats()
    {
         return [
            'datetime'=>[//字段名
                [
                    'action'=> ['index'],
                    'data'=> function($value, $data){
                        return date("Y-m-d H:i:s", $value); 
                    }
                ],
                [
                    'action'=> ['xls'],
                    'data'=> function($value, $data){
                        return date("Y年m月d日", $value); 
                    }
                ],
            ]
        ];
    }

9. 表單搜索設置


clipboard.png

用好yii\db\Query查詢構建器包括關聯表查詢,儘可能不要直接寫sql語句。
控制器和視圖中所用的字典類,獲取數據的方法都應寫到Model裏。

backend/modules/test/models/TestSearch.php
配置好search方法,根據需求來肯定字段搜索是like仍是=或者其餘。
可參考Yii2的yii\db\QueryandFilterWhere等方法和操做符格式
andFilterWhere可放心使用,搜索時字段非空纔會執行。
http://www.yiichina.com/doc/guide/2.0/db-query-builder

backend/modules/test/models/TestSearch.php

public function search($query, $params = [])
{
    $params = $params ? : Yii::$app->request->getQueryParams();
    $this->attributes = $params;

    $start_time = ArrayHelper::getValue($params, 'start_time');//至關於isset($params['start_time']) ? $params['start_time'] : NULL;
    $end_time = ArrayHelper::getValue($params, 'end_time');

    $query->andFilterWhere([
        'status' => $this->status,
    ]);

    $query->andFilterWhere(['like', 'name', $this->name])
        ->andFilterWhere(['like', 'remark', $this->remark])
        ->andFilterWhere(['between', 'datetime', $start_time ? strtotime($start_time.' 00:00') : NULL, $end_time ? strtotime($end_time.' 23:59') : NULL]);
    return $query;
}

得出的sql是:

SELECT * FROM `test` WHERE ((`status`=:qp0) AND (`name` LIKE :qp1)) AND (`datetime` BETWEEN :qp2 AND :qp3) ORDER BY `hid`
  1. 字段排序


backend/modules/test/models/Test.php
須要繼承自 base\BaseActiveRecord
定義參與排序的字段:

class Test extends \common\models\test\Test{     
    //排序字段
    public $sortFields = ['percent', 'datetime'];

backend/modules/test/controllers/DefaultController.php

$model = $this->findModel();
$search_model = new TestSearch;
$query = $model::find()->select(['*']);
$query = $search_model->search($query);
$sort = $search_model->sortOrderBy('`test`.`hid` asc');//默認的排序字段
$query->orderBy($sort);

backend\modules\test\views\default_form.php

設置排序連接和樣式

<th width="120" class="<?=$model->sortQueryParams('percent', 'class');?>" onClick="window.location.href='<?=$model->sortQueryParams('percent', 'link');?>';">佔百分比</th>

效果:

clipboard.png

  1. 視圖及表單,


視圖裏儘可能避免編寫複雜的邏輯。

因爲默認生成的表單控件都是input,
接下來須要修改createupdate的視圖文件(表單)。
按照業務需求設置好字段的表單控件和驗證規則

backend\modules\test\views\default_form.php

表單元素爲必填項的在lable上的class加上form-required,即:

<label class="col-sm-2 control-label form-required"><?=$model->getAttributeLabel('name');?></label>

clipboard.png

經常使用的表單控件類型有:
backend/modules/test/models/Test.php 裏定義好了Status的字典

/**
     * @status
     */
    public static function Status($key = false){
        $array = [
            '0'=> '有效',
            '2'=> '鎖定'
        ];
        if ($key === false){
            return $array;
        }else{
            return isset($array[$key]) ? $array[$key] : '';
        }
        
    }

單行文本框:

<?= Html::input('text', 'Test[name]', $model->name, ['class' => 'form-control']) ?>

或者

<?=  Html::activeInput('text', $model, 'name', ['class' => 'form-control']) ?>

clipboard.png

多行文本框:

<?= Html::textarea('Test[name]', $model->name, ['class' => 'form-control']) ?>
<?= Html::activeTextarea($model, 'name', ['class' => 'form-control']) ?>

clipboard.png

下拉列表:

<?=Html::dropDownList('Test[status]', $model->status, $model::Status(), ['class' => 'form-control m-b']);?>
<?=Html::activeDropDownList($model, 'status', $model::Status(), ['class' => 'form-control m-b']);?>

clipboard.png

複選框

<?= Html::checkboxList('Test[status]', $model->status, $model::Status());?>  
<?= Html::activeCheckboxList($model, 'status', $model::Status());?>

clipboard.png

單選框

<?= Html::radioList('Test[status2]', $model->status, $model::Status());?>
<?= Html::activeRadioList($model, 'name', $model::Status()) ?>

clipboard.png

單選列表

<?= Html::listBox('Test[status3]', $model->status, $model::Status(), ['class'=>'form-control']);?>
<?= Html::activeListBox($model, 'status', $model::Status(), ['class'=>'form-control']);?>

clipboard.png

多選列表

<?= Html::listBox('Test[status4]', $model->status, $model::Status(), ['multiple'=>true, 'class'=>'form-control']);?> 
<?= Html::activeListBox($model, 'status', $model::Status(), ['multiple'=>true, 'class'=>'form-control']);?>

clipboard.png

切換開關

<?= Html::checkbox('Test[status5]', $model->status, ['class'=> 'js-switch']);?> <?= Html::checkbox('HabitusTest[status6]', $model->status, ['class'=> 'js-switch']);?>   
<?= Html::activeCheckboxList($model, 'status', $model::Status(), ['class'=> 'js-switch']);?>

clipboard.png

下拉選擇帶搜索

<?=Html::dropDownList('Test[status9]', '120000', $model::City(), ['prompt'=>'--請選擇--', 'data-placeholder'=>'選擇省份...', 'class'=>'chosen-select', 'style'=>'width:350px;', 'tabindex'=>'2']);?>
<?=Html::activeDropDownList($model, 'status', $model::City(), ['prompt'=>'--請選擇--', 'data-placeholder'=>'選擇省份...', 'class'=>'chosen-select', 'style'=>'width:350px;', 'tabindex'=>'2']);?>

clipboard.png

下拉多選帶搜索

<?=Html::dropDownList('Test[status9]', ['120000','110000'], $model::City(), ['multiple'=>true, 'data-placeholder'=>'選擇省份...', 'class'=>'chosen-select', 'style'=>'width:350px;', 'tabindex'=>'2']);?>
<?=Html::activeDropDownList($model, 'status', $model::City(), ['multiple'=>true, 'data-placeholder'=>'選擇省份...', 'class'=>'chosen-select', 'style'=>'width:350px;', 'tabindex'=>'2']);?>

clipboard.png

表單驗證規則 示例
更詳細的驗證方法參考:[jQuery.validate][10] 插件

<script>  
$(function () {        
    $("#view-form-form").validate({
        //debug:true, //若是隻調試驗證不提交數據,可開啓這裏
        rules: {
           'Test[name]':{
               required:true,//必填
               maxlength: 50 //最大長度
            },
            //其餘的字段的驗證...
        },
        ignore:"",//驗證包括hidden的input元素
        messages: {
            'Test[name]':{
                required:'請輸入體質名稱',//未輸入提示
                maxlength:'體質名稱輸入太長'//超出最大長度提示
            },
        }
    });
});
</script>
  1. 保存表單數據到數據庫


瘦控制器 胖模型

$model->sava()前會根據Model類的rules()方法定義規則去校驗數據

backend/modules/test/models/Test.php

/**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['name'], 'required'],//必填
            [['percent', 'listorder', 'datetime', 'status', 'created_by', 'updated_by'], 'integer'],//必需爲數字
            [['name'], 'string', 'max' => 300],//最長300
            [['remark', 'hearttrait', 'common', 'nacs', 'attack'], 'string', 'max' => 500]//字符串,最長500
        ];
    }

guide: 詳細的rules
數據驗證不經過時能夠根據打印$model->getErrors()查看具體錯誤信息

對於表單提交過來的數據不是最終保存到數據庫裏的格式時,如時間戳等,
能夠經過自定義rules或者重組表單數據來實現:(還有其餘方法也能夠實現)

backend/modules/test/models/Test.php

public function validateCountry($attribute, $params)
    {
        $this->$attribute = 'new '.$this->$attribute;//這裏能夠從新設置name的值
        //也能夠使用自定義驗證規則
        //if (!in_array($this->$attribute, ['USA', 'Web'])) {
            //$this->addError($attribute, 'The country must be either "USA" or "Web".');
        //}
    }
    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            ['name', 'validateCountry'],
            [['name'], 'required'],
            [['percent', 'listorder', 'datetime', 'status', 'created_by', 'updated_by'], 'integer'],
            [['name'], 'string', 'max' => 300],
            [['remark', 'hearttrait', 'common', 'nacs', 'attack'], 'string', 'max' => 500]
        ];
    }

或者咱們用behaviors來實現一些字段的數據的自動化填充

backend/modules/test/models/Test.php

public function behaviors()
    {
        return [
            [
                'class' => 'yii\behaviors\BlameableBehavior',
                'createdByAttribute' => 'created_by',//create時,created_by字段的值會自動填充爲當前操做用戶的ID:Yii::$app->user->identity->id;
                'updatedByAttribute' => 'updated_by',
            ],
            'timestamp' => [
                'class' => 'yii\behaviors\TimestampBehavior',
                'attributes' => [
                    //insert數據庫前datetime的值會自動填充爲當前的時間戳
                    BaseActiveRecord::EVENT_BEFORE_INSERT => ['datetime'],
                    //BaseActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
                ],
            ],
        ];
    }
相關文章
相關標籤/搜索