MVVM架(jia)構~knockoutjs系(xi)列之擴(kuo)展(zhan)ajax驗(yan)證(zheng)~驗(yan)證(zheng)數據是(shi)否存(cun)在
在大部分網站里,用戶(hu)名(ming)都是唯(wei)一(yi)的,即當用戶(hu)注(zhu)冊時,如果用戶(hu)輸入(ru)的名(ming)字(zi)不合法(fa),我們(men)需要提示用戶(hu),讓(rang)用戶(hu)再起個新(xin)名(ming)字(zi),而這種復雜(za)的驗證一(yi)般是通(tong)過JS來實現的,如果把它集(ji)成到ko里,那(nei)就完美了(le).有了(le)這個想法(fa),我開始嘗試它,相信(xin)一(yi)定可(ke)以成功的!
起初在設計時(shi)出現(xian)了(le)很(hen)多問(wen)題,如ajax異步問(wen)題,延(yan)時(shi)處理問(wen)題,ajax返(fan)回值(zhi)問(wen)題等等,經過幾次失(shi)敗后,在總(zong)結了(le)相關知識后,終(zhong)于設計出來(lai)了(le)一個不錯的擴展,即 ajaxData驗證方式.
擴展ko.validation.js代碼
kv.rules['ajaxData'] = { validator: function (val, ajaxMethod) { var result = true; $.when(ajaxMethod(val)).then(function (data) { result = kv.utils.isEmptyVal(val) || data; //val為空走reqired邏輯,不為空再走ajax邏輯 }); return result; }, message: 'Please enter info is no corrent.' };
HTML代碼
function existUser(name) { return $.ajax({ //必須(xu)加return才可以(yi)將它(ta)返回(hui) url: "/ef/IsNotExist?name=" + name, type: "get", dataType: "json", async: false, success: function (data) { return data; } }); }
調用方式
self.UserName = ko.observable().extend({ minLength: 2, maxLength: { params: 30, message: "名稱最大長度(du)為30個字符" }, required: { params: true, message: "請輸(shu)入名(ming)稱" }, ajaxData: { params: existUser, message: "用戶已(yi)經存在" } });
運行后的效果如圖
最(zui)后要說明的(de)一點是(shi),目(mu)前ajax只能使用同步(bu)方(fang)式,因為在ko.validation內部有一個機制,如果程(cheng)序沒有返回,那么驗(yan)證會返回false,即(ji)驗(yan)證失敗,如對于異步(bu)請求來(lai)說,它(ta)不會阻塞(sai)當(dang)前線程(cheng)的(de)執(zhi)行,所以,它(ta)會直接輸出false,而不走(zou)我們的(de)驗(yan)證程(cheng)序.