1. 開啓gii模塊
common/config/main-local.php
加入下面代碼javascript
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/giiphp
或者http://localhost/項目目錄/backend/index.php/?r=giijava
3. 生成模塊
之後臺模塊爲示例:Module Class
填寫要生成module
的路徑Module ID
填寫模塊名Code Template
選擇咱們自定義好的Module
生成模板sql
若是生成成功會顯示以下:數據庫
4. 生成公共模型
生成一個公共模型,方便不一樣入口應用複用和繼承。app
生成成功會顯示以下:yii
5. 生成後臺私有模型
生成後臺私有模型,並繼承公共模型,在該類中實現後臺私有的方法。ide
生成成功會顯示以下:函數
6. 生成CRUD
操做和視圖
去掉用不到的視圖文件ui
生成成功會顯示以下:
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`
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. 表單搜索設置
用好yii\db\Query
查詢構建器包括關聯表查詢,儘可能不要直接寫sql語句。
控制器和視圖中所用的字典類,獲取數據的方法都應寫到Model
裏。
在backend/modules/test/models/TestSearch.php
中
配置好search
方法,根據需求來肯定字段搜索是like仍是=或者其餘。
可參考Yii2的yii\db\Query
的 andFilterWhere
等方法和操做符格式 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`
-
字段排序
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>
效果:
-
視圖及表單,
視圖裏儘可能避免編寫複雜的邏輯。
因爲默認生成的表單控件都是input
,
接下來須要修改create
和update
的視圖文件(表單)。
按照業務需求設置好字段的表單控件和驗證規則
backend\modules\test\views\default_form.php
表單元素爲必填項的在lable
上的class
加上form-required
,即:
<label class="col-sm-2 control-label form-required"><?=$model->getAttributeLabel('name');?></label>
經常使用的表單控件類型有: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']) ?>
多行文本框:
<?= Html::textarea('Test[name]', $model->name, ['class' => 'form-control']) ?> <?= Html::activeTextarea($model, 'name', ['class' => 'form-control']) ?>
下拉列表:
<?=Html::dropDownList('Test[status]', $model->status, $model::Status(), ['class' => 'form-control m-b']);?> <?=Html::activeDropDownList($model, 'status', $model::Status(), ['class' => 'form-control m-b']);?>
複選框
<?= Html::checkboxList('Test[status]', $model->status, $model::Status());?> <?= Html::activeCheckboxList($model, 'status', $model::Status());?>
單選框
<?= Html::radioList('Test[status2]', $model->status, $model::Status());?> <?= Html::activeRadioList($model, 'name', $model::Status()) ?>
單選列表
<?= Html::listBox('Test[status3]', $model->status, $model::Status(), ['class'=>'form-control']);?> <?= Html::activeListBox($model, 'status', $model::Status(), ['class'=>'form-control']);?>
多選列表
<?= Html::listBox('Test[status4]', $model->status, $model::Status(), ['multiple'=>true, 'class'=>'form-control']);?> <?= Html::activeListBox($model, 'status', $model::Status(), ['multiple'=>true, 'class'=>'form-control']);?>
切換開關
<?= 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']);?>
下拉選擇帶搜索
<?=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']);?>
下拉多選帶搜索
<?=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']);?>
表單驗證規則 示例
更詳細的驗證方法參考:[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>
-
保存表單數據到數據庫
瘦控制器 胖模型
$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'], ], ], ]; }