yii 2.0 自帶驗證與jquery validate結合的一次嘗試
阿新 • • 發佈:2019-02-17
背景:在公司DMS系統,使用的是Yii 2.0的框架,而前端驗證使用的是validate,之前的做法是在前端驗證完以後,資料傳到後端,自己寫驗證,大概就是這種畫風
//php頁面
if (empty($data['chinese_name'])) {
exit($this->jsonFailedResponse('中文名稱不能為空'));
}
if (empty($data['foreign_name'])) {
exit($this->jsonFailedResponse('外文名稱不能為空'));
}
if (empty($data['company_id'])) {
exit ($this->jsonFailedResponse('公司不能為空'));
}
if (empty($data['brand_id'])) {
exit($this->jsonFailedResponse('品牌不能為空'));
}
if (empty($data['mp_serial_id'])) {
exit($this->jsonFailedResponse('系列不能為空'));
}
if (empty($data['weight'])) {
exit($this->jsonFailedResponse('重量不能為空' ));
}
if (empty($data['package'])) {
exit($this->jsonFailedResponse('請選擇包裝'));
}
//前端js頁面
if ('succeed' == r.status) {
if (url!='') {
common_layer(r.message, url);
} else {
common_layer(r.message,document.referrer);
}
} else {
//不重新整理
if (empty(r.message) && !empty(r.data)) {
showRuleErrors(r.data);
} else {
common_layer(r.message);
}
}
看起來是挺整齊的,但是其實很不合理, 首先在後端,yii本來就有rules的驗證,在前端,本來使用validate來提示,後面又使用layer的彈出來提示,給人一種很不統一的感覺。
兩個問題,首先解決後端的問題,解決方案:使用Yii自帶的驗證,首先寫model
<?php
class MbProduct extends \app\core\base\BaseActiveRecord {
public static function tableName(){
return 'mb_product';
}
//關鍵在這裡,在這裡寫規則,return 裡面寫陣列,第一個引數是欄位,第二個是引數規則,第三個引數是錯誤資訊
public function rules(){
return [
[['overall_height', 'bottle_height', 'diameter', 'volume', 'weight'], 'number','message'=>'必須為數字'],
[['brand_id','sell_area_id','made_area_id'], 'required', 'message' => '請選擇'],
];
}
}
使用
//例項化model
$model = new XXX()
//把要儲存的值賦給model
$model->attributes = $data;
//驗證
if ($model->validate()) {
//通過rules驗證
if ($model->save()) {
return ['code'=>'1','model'=>$model];
}
return ['code'=>'0'];
} else {
//沒通過
return ['code'=>'2','error'=>$model->getErrors()];
}
這樣的話,就不用自己寫驗證了,但是要怎麼和validate結合起來呢,關鍵在於$model->getErrors()的返回資訊
[chinese_name] => Array ( [0] => 該產品已經存在! ) )
可以看到,有欄位名字和錯誤資訊,那麼就簡單了,只要返回給前端,交給js的validate就可以了
//js
//接收後端驗證的錯誤資訊,模擬jQueryvalidate彈出錯誤資訊(需要配和yii的rules使用)
//這裡的error這個引數就是後端返回來的資訊,我這裡不是直接呼叫validate的api,直接自己寫了提示
var showRuleErrors = function(error) {
$.each(error, function(index, val) {
var input_id = index;
$('#'+input_id).attr({
"aria-describedby" : input_id + "-error",
}).after('<span id="'+input_id+'-error" class="help-block m-b-none">'+val+'</span>').parents('.form-group').addClass('has-error');
});
}
後記:關於這次想法其實是需求方提出來的,我只是執行了而已,但是在實現的過程中,可以多思考,不要一下子就覺得不可能。
還有,yii的rule其實是支援自定義規則和場景的,還有怎麼和validate跟好的結合這個也還沒解決