Ajax表單提交及后台處理簡單應用


      首先先說下表單提交吧,要提交表單那么就得先收集表單數據(至於驗證這個我就不說了,要說留下下次吧),有了jquery取個html的值還是簡單$("xxid").val()等就完了,但如果一張表單收集的數據很多,像這樣的表單又有很多張,那用此方法肯定麻煩死,並且容易眼花錄錯。所以,我們就可以簡單的來定義一個收集規則,如在要回傳到服務器的數據表單控件,可以做個標記,到時取的時候把這些標記的數據一起取回去。

    就拿最簡單的文體輸入做例子吧<input type="text" id="txtcode" name="txtcode" datafield="Code" style="width: 200px" />我們加一個"datafield"屬性,存入的值為對應服務器相關類的屬性名。有了這標記前台取數據就好辦了。我們可以定個通用方法如下面代碼

    getFormData: function(formid) {       
        var data = {};

        //獲取TEXT文件內容
        $("#" + formid + " input[type=text]").each(function(i, o) {
            var jo = $(o);
            if (jo.attr("datafield")) {
                var str = jo.val();
                str = str.replace(" ", "");
                if (str !== "") {                    
                    data[jo.attr("datafield")] = jo.val();
                }
            }
        });
        return data;
}

這里就是一個簡單的獲取表單里面所有text文本,並放入到一個data對象里面,至於其它表單控件值怎么取我就不多說了,原理差不多。

那么接下回就是把數據發到服務器上了,我這里就直接用jquery帶的ajax。

  var save = function(sender) {         
            $(sender).prop("disabled", true); //禁用按鈕,防止重復發送
            var data =  getFormData("form1");
            var jsonobj = { jsondata: data };
            var textdata = JSON.stringify(jsonobj);
            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "xxxxx.aspx/Save",
                dataType: "json",
                data: textdata,
                success: function(msg) {
                    if (msg.d == "1") {
                        document.form1.reset();
                        alert("保存成功!");                      
                    }
                    else if (msg.d == "0") {
                        alert("保存失敗!");
                    }
                },
                complete: function(jqXHR, textStatus) {
                    $(sender).prop("disabled", false); //還原按鈕
                }
            });
        }

這里的"xxxxx.aspx/Save"就是ajax處理頁面,其它就是一個webmethod。做了一下防止客戶手速太快,服務處理太慢,重復點擊的處理。

這樣一個表單數據收集,回傳服務器就完成了。這里使用json2.js的JSON.stringify方法統一將對象轉成json字符,好處就是不用自己為拼json字符串而考慮json的格式問題,簡單干凈。

那么客戶已經把數據收錄好了,服務器也該要處理數據了。我們從前台來的數據的鍵(json的key),不可能全部包括某個數據類的所有屬性。並且數據類也有很多個,應該是哪一個類只有服務器才知道。所以這里我們就需要寫一個幫助的轉換類。這里又有問題,有可能數據類有很多個,難道我要為每一個類寫一個方法,那不是個坑么?所以我們分析下客戶端傳到服務端上的數據格式,它是一組鍵值對且不會重復,那么就相當於一個Dictionary<string, string>,后台的類有很多種,那么至少我們能確定一個傳入參數了,傳出的就是相關類。相關類?到底是哪一類還只有到了具體后台收集方法里才知道。那么,整理一下思路,現在有一個Dictionary<string, string>要變成一個數據類,數據類到底是什么有什么樣的屬性?搞不清,但這個Dictionary<string, string>的key(鍵)可以看做是這個數據類屬性集的一個子集,而這個Dictionary<string, string>的value(值)是這個數據類屬性值toString()的子集。那樣這樣就好辦了。屬性集怎么取?反射。這么多類到底是哪個?不管它,泛型解決。說下這么多,貼下核心代碼

        public static T1 UpdateObjectByDic<T1>(T1 scrobj, IDictionary<string, string> sourceobject, bool ignoreCase)
         where T1 : new()
        {
            T1 result = scrobj;
            PropertyInfo[] pifresults = typeof(T1).GetProperties();
            foreach (var dic in sourceobject)
            {
                foreach (PropertyInfo pifresult in pifresults)
                {
                    if (string.Compare(dic.Key, pifresult.Name, ignoreCase) == 0)
                    {
                      pifresult.SetValue(result, ChangeType(dic.Value, pifresult.PropertyType), null);
                        break;
                    }
                }
            }
            return result;
        }

        public static Object ChangeType(object value, Type targetType)
        {
            Type convertType = targetType;
            if (targetType.IsGenericType && targetType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                NullableConverter nullableConverter = new NullableConverter(targetType);
                convertType = nullableConverter.UnderlyingType;

            }
            return Convert.ChangeType(value, convertType);
        }

我這里T1 scrobj是把更新做在一起,如添加表單就傳個new的對象進來,如果是更新把單就把原表單數據傳進來。這里順帶說下ChangeType方法,其它就是數據類里有些屬性是nullable的(int? DateTime?等)傳統的Convert.ChangeType會有異常所以就簡單改了下,ignoreCase就是屬性(前台那個datafield對應的值)查找是否處理大小寫(一般是不管大小寫的,要管大小寫相信會被前台口水流淹死)。

這樣后台數據處理核心就完了,調用部分代碼也貼下

[WebMethod(EnableSession = true)]
        public static string Save(Dictionary<string, string> jsondata)
        {
            string result = "0";
            Model.Project pro =  ConvertHandle.UpdateObjectByDic< Model.Project>(jsondata,new Model.Project,true);            
            pro.CreatorID = BLL.Sys_User.GetCurUser().ID.ToString();
            pro.CreatorName = BLL.Sys_User.GetCurUser().Name;       
            prohandle.Insert(pro);
            result = "1"; 
            return result;
        }

這里就是后台具體處理方法調用的核心使用了,prohandle.Insert(pro)將類存入數據庫,pro.CreatorID,pro.CreatorName為項目的一些其它信息,這些就不說了。到這里一個表單前台數據收集,后台處理,除了保存那塊以外,就都算完了,呵呵。

     文章最后說下,這里只是個簡單應用,像我說的這前台收集,很多前台js框架都已經早做了,考慮方面也比我這個全面得多,后台處理我這是基於我這種前台簡單收集弄的,很多第三方框架都有完整的體系了,但我這里說的只是一種簡單的思路,當你一時沒有那么多控件時是否能把這一條路簡單走通實現。當然我強烈建議不要重復造輪子,但要一定要明白輪子的核心作用和原理。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM