很常見的業務場景,就是前端一個表單,submit給后台,在web.form時代,有from 的runat="server" 配合submit 自動會提交給服務端,然后服務端解析Request裝填對象。 如果要是異步提交的話,就麻煩點,from表單不會自動把你的所有value傳給后台,於是就一個一個獲取value值,通過json對象異步提交給后台,然后再由后台一個一個解析,再封裝給對象。
$.post("Handler1.ashx", { Name: $("#txtName").val(), Age: $("#txtAge").val() }, function (res)
{...})
很慶幸的是上面只有2個參數,如果需要提交有10多個參數的話,用這種方法相信大家都有手疼的感覺。
幸虧在jquery上有serializeArray方法,可以不關心表單內容,只要有name屬性,就會直接匹配value或者test值,生成一個json對象。如下:
<form id="createStudent_form" runat="server"> <table> <tr><td>Name:</td><td><input type="text" name="Name" /></td></tr> <tr><td>Address:</td><td><input type="text" name="Address" /></td></tr> <tr><td>Sex:</td><td>男<input type="radio" name="Sex" value="1" /> 女<input type="radio" name="Sex" value="0" /></td></tr> <tr><td>Remark:</td><td><textarea name="Remark"></textarea></td></tr> <tr><td><input type="button" value="submit" id="submit_btn" /></td></tr> </table> </form>
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script>
$(function () {
$("#submit_btn").click(function () {
var json = $("#createStudent_form").serializeArray();
console.log(JSON.stringify(json));
});
})
</script>
點擊提交表單,打印出來的結果是:
[{"name":"__VIEWSTATE","value":"fO0ZxNMqIPEgrnZBjZiR5a97V4u8fbMcDpPStT/X97Cpp7vbUjNufjDdDOZHM9ey+6OYvgcTT5+6sQKR+z1cX2vB+INYHkDkWLSKiEgOuEI="},{"name":"Name","value":"2323"},{"name":"Address","value":"3223"},{"name":"Sex","value":"1"},{"name":"Remark","value":"23232"},{"name":"__VIEWSTATEGENERATOR","value":"2D79A64A"}]
一看是個json 對象數組,除了第一個是webForm獨有的shit東西以外,其他大家一眼可以看出來是name,value兩個鍵值對相匹配。這與我們想要得到的格式{name:value}還不太一致,當然jquery做到這一步已經不錯了(其實內部實現原理也不難,拿到表單一一遍歷組成Json),剩下的就需要咱們自己擴展了。簡單改造如下:
$.fn.serializeJson = function () { var resultJson = {}; var array = this.serializeArray(); $(array).each(function () { resultJson[this.name]=this.value; }); return resultJson; };
通過上面的方法就得到了咱們想要的結果集了,但是這只是最基本的擴展,你可以繼續深化比如支持相同內容的多個表單提交,支持相同name的多選框等等。
咱們異步提交給后端看看:
$("#submit_btn").click(function () {
var StudentModel = $("#createStudent_form").serializeJson();
console.log(JSON.stringify(StudentModel));
$.post("Handler1.ashx", StudentModel, function (res) {
}).error(function ()
{ alert("error!") })
});
})
相信到了這一步后,用過Mvc的小伙伴們看了一下子就興奮起來了,因為Action會自動轉化類型,只要你在后台定義過一個StudentModel對象,其參數和name一致,然后不用關系Requset就可以直接拿到了對象的值,這簡直是爽呆了,幾乎是太簡單了。如下:
希望能多少給你點幫助。
最后再反向操作下,給了Json對象 ,如何自動把值賦給表單中的元素:
數據源:
public ActionResult Index()
{
return View();
}
public ActionResult LoadAll()
{
List<Test> list = new List<Test>();
Test test1 = new Test() {
Id=1,
Name="xxx",
Title="xxx",IsCheck=false,
ClassId=1
};
list.Add(test1);
return Json(list);
}
}
public class Test
{
public int Id { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public bool IsCheck { get; set; }
public int ClassId { get; set; }
}
前端:
<script>
$(function () {
load();
})
function syncJsonTofrom($form,entity)
{
for (var key in entity) {
var $control = $form.find("[name=" + key + "]");
if ($control) {
if ($control.attr("type") == "checkbox" && entity[key]) {
$control.attr("checked", true);
}
$control.val(entity[key]);
}
}
}
function load() {
$.post("/Test/LoadAll", function (res) {
var entity = res[0];
syncJsonTofrom($("#frm"),entity);
})
}
</script>
<form id="frm">
ID:
<input type="text" name="Id" />
NAme:
<input type="text" name="Name" />
Title
<input type="text" name="Title" />
Ischeck<input type="checkbox" name="IsCheck" />
class
<select name="ClassId">
<option value="0">xxx</option>
<option value="1">222
</option>
<option value="2">222333
</option>
</select>
</form>
