您好,登錄后才能下訂單哦!
本篇文章為大家展示了ASP.NET MVC中怎么綁定數(shù)組模型,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
在ASP.NET MVC中使用Razor語(yǔ)法可以在視圖中方便地展示數(shù)組,如果要進(jìn)行數(shù)組模型綁定,會(huì)遇到索引斷裂問(wèn)題,如下示例:
<input type="text" name="[0].Name" /> <input type="text" name="[1].Name" /> <input type="text" name="[2].Name" /> <input type="text" name="[4].Name" /> <input type="text" name="[5].Name" />
數(shù)組Name在索引3處斷裂,在模型綁定器解析完成后,會(huì)丟棄后面的4和5,只有0、1、2會(huì)被正確解析到對(duì)應(yīng)模型中。
這種斷裂在進(jìn)行動(dòng)態(tài)數(shù)組綁定時(shí)會(huì)經(jīng)常發(fā)生。
下面,以一個(gè)案例來(lái)探討如何進(jìn)行動(dòng)態(tài)數(shù)組綁定。假設(shè)有以下應(yīng)用場(chǎng)景:
要求能夠動(dòng)態(tài)地添加和刪除乘機(jī)人,最終提交表單后乘機(jī)人信息要填充到視圖模型中的一個(gè)數(shù)組或集合屬性中,以方便我們進(jìn)行后續(xù)業(yè)務(wù)處理。
方式一:使用占位符替換
第一種方式我稱(chēng)之為”占位符替換“,使用的是ASP.NET MVC默認(rèn)的模型綁定器(DefaultModelBinder)并結(jié)合前端處理。
首先,第一步,根據(jù)業(yè)務(wù)場(chǎng)景設(shè)計(jì)視圖模型:
public class OrderModel { /// <summary> /// 航班號(hào) /// </summary> public string FlightNo { get; set; } /// <summary> /// 乘機(jī)人 /// </summary> public List<Passenger> Passengers { get; set; } } public class Passenger { public string Name { get; set; } public string IdNo { get; set; } }
其次,將此視圖模型傳遞給視圖:
public ActionResult New() { Models.OrderModel orderModel = new Models.OrderModel(); List<Models.Passenger> passenger = new List<Models.Passenger>(); passenger.Add(new Models.Passenger()); orderModel.Passengers = passenger; return View(orderModel); }
再在視圖文件中進(jìn)行展示:
<div > <div class="form-group"> <label>航班</label><br/> @Html.TextBoxFor(p => p.FlightNo, new { placeholder = "航班號(hào)" }) </div> <div class="form-group"> <label>乘機(jī)人</label> <table class="passenger" > <tbody> @if (Model.Passengers != null && Model.Passengers.Count > 0) { for(int i = 0; i < Model.Passengers.Count; i++) { <tr> <td>姓名:</td> <td>@Html.TextBoxFor(p => Model.Passengers[i].Name)</td> <td>身份證號(hào):</td> <td>@Html.TextBoxFor(p => Model.Passengers[i].IdNo)</td> <td> <a href="javascript:;" onclick="removePassenger(this)" >刪除</a> </td> </tr> } } </tbody> </table> <div > <a href="javascript:;" onclick="addPassenger()">添加乘機(jī)人</a> </div> </div> </div>
由于ASP.NET MVC的模型綁定器(DefaultModelBinder)具備自動(dòng)解析形如"[0].屬性名"、"[1].屬性名"的能力,所以可以在模板文件中以占位符的形式來(lái)表示數(shù)組下標(biāo):
<!-- 乘機(jī)人模板 --> <script type="text/html" id="passengerTemplate"> <tr> <td>姓名:</td> <td><input id="Passengers_{}__Name" name="Passengers[{}].Name" type="text" value=""></td> <td>身份證號(hào):</td> <td><input id="Passengers_{}__IdNo" name="Passengers[{}].IdNo" type="text" value=""></td> <td> <a href="javascript:;" onclick="removePassenger(this)">刪除</a> </td> </tr> </script>
以上代碼中的"{}"是數(shù)組下標(biāo)占位符。當(dāng)添加乘機(jī)人時(shí),可預(yù)先計(jì)算已有乘機(jī)人個(gè)數(shù),然后再使用JavaScript替換”{}“為數(shù)組下標(biāo)。
// 添加乘機(jī)人 function addPassenger() { // 當(dāng)前添加行數(shù)組元素下標(biāo) var index = $(".passenger").find("tbody").find("tr").length; //{}是數(shù)組元素下標(biāo)占位符 var passengerHTML = $('#passengerTemplate').html().replace(/{}/g, index); $(".passenger").find("tbody").append(passengerHTML); }
當(dāng)刪除乘機(jī)人時(shí),注意如果刪除的不是最后一個(gè),會(huì)發(fā)生索引斷裂問(wèn)題,需要重新調(diào)整數(shù)組下標(biāo):
// 刪除乘機(jī)人 function removePassenger(e) { $(e).parents("tr").remove(); // 依次遍歷表格的每行,重新調(diào)整數(shù)組下標(biāo) var tb = $(".passenger").first(); var count = tb.find("tbody").find("tr").length; for (var i = 0; i < count; i++) { var newTR = tb.find("tr").eq(i).formhtml().replace(/\[\d+\]/g, '[' + i + ']');//重新調(diào)整數(shù)組元素下標(biāo) tb.find("tr").eq(i).html(newTR); } }
這樣,當(dāng)我們提交表單時(shí),乘機(jī)人信息就會(huì)自動(dòng)填充到模型的Passengers屬性中。
方式二:使用Vue.js
使用第一種方式需要編寫(xiě)大量前端代碼,包括模板文件,添加刪除事件,還需要處理重新調(diào)整順序時(shí)的插值問(wèn)題。
如果使用前端MVVM框架會(huì)讓這一流程變得簡(jiǎn)單,目前比較流行的前端MVVM框架有AngularJS,有老古董KnockoutJS,也有新興小眾框架Vue.js。
AngularJS比較龐大,這么簡(jiǎn)單的一個(gè)模型綁定用Anuglar有一種殺雞用牛刀的感覺(jué);Knockout和Vue都是輕量級(jí)的MVVM框架,但Knockout需要包裹原生數(shù)據(jù)來(lái)制造可觀察對(duì)象,取值和賦值時(shí)需要采用函數(shù)調(diào)用的形式,使用起來(lái)不是很方便,所以我選擇了Vue.js。Vue.js是一個(gè)輕量高效的庫(kù),它沒(méi)有像Angular的module、controller、scope、factory、service這種API,核心就是一個(gè)模型綁定功能。大小只有70kb,gzip壓縮后只有25kb,非常輕量化。
這種方式的基本原理是前端使用Vue.js聲明視圖模型并進(jìn)行綁定,然后提交表單時(shí)把模型序列化為json字符串傳遞到后臺(tái),后臺(tái)再使用Json.net反序列化為C#對(duì)象。
由于Vue.js的綁定特點(diǎn),我們只需要操作數(shù)組元素即可,不需要額外關(guān)注DOM操作,節(jié)省了不少工作量。
首先,需要聲明視圖模型,并使用Vue.js進(jìn)行綁定:
<script src="~/Scripts/vue.js"></script> <script type="text/javascript"> // 視圖模型 var viewModel = { FlightNo: '', Passengers: [ { ElementId: 'passenger_1', Name: '', IdNo: '' } ] } // 模型綁定 new Vue({ el: '#app', data: viewModel, methods: { removePassenger: function (elementId) { for (var i = 0; i < viewModel.Passengers.length; i++) { if (viewModel.Passengers[i].ElementId == elementId) { viewModel.Passengers.splice(i, 1); } } }, addPassenger: function () { var tb = document.getElementsByTagName('table')[0]; var index = tb.rows[tb.rows.length - 1].getElementsByTagName('input')[0].getAttribute("id").split('_')[1]; viewModel.Passengers.push({ Name: '', IdNo: '', ElementId: 'passenger_' + (index + 1) }); }, submitForm: function () { var jsonString = JSON.stringify(viewModel); document.getElementById("viewModel").value = jsonString; return true; } } }); </script>
然后,在視圖中使用Vue.js綁定:
<form action="/Order2/NewPost" method="post"> <div id="app" > <div class="form-group"> <label>航班</label><br /> <input v-model="FlightNo" type="text" placeholder="航班號(hào)" /> </div> <div class="form-group"> <label>乘機(jī)人</label> <table class="passenger"> <tbody> <tr v-for="passenger in Passengers"> <td>姓名:</td> <td><input v-model="passenger.Name" v-bind:id="passenger.ElementId" type="text" /></td> <td>身份證號(hào):</td> <td><input v-model="passenger.IdNo" type="text" /></td> <td> <a href="javascript:;" v-on:click="removePassenger(passenger.ElementId)">刪除</a> </td> </tr> </tbody> </table> <div > <a href="javascript:;" v-on:click="addPassenger">添加乘機(jī)人</a> </div> <div > <input type="submit" class="btn btn-default" v-on:click="submitForm" /> </div> </div> </div> <input type="hidden" id="viewModel" name="viewModel" /> </form>
最后在Controller里,我們反序列化即可得到對(duì)應(yīng)的C#強(qiáng)類(lèi)型模型:
[HttpPost] public ActionResult NewPost() { var jsonString = Request.Form["viewModel"]; Models.OrderModel model = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.OrderModel>(jsonString); if (model != null) { // our code here... } return RedirectToAction("Index", "Home"); }
這兩種方式均可以實(shí)現(xiàn)動(dòng)態(tài)數(shù)組綁定,方式一使用js進(jìn)行占位符替換,表單中的元素都以[index].屬性名的方式命名,然后由MVC默認(rèn)的模型綁定器來(lái)轉(zhuǎn)化模型;
方式二使用Vue.js來(lái)直接進(jìn)行模型綁定,提交表單時(shí)將模型序列化為json字符串,然后后端再反序列化,最終得到強(qiáng)類(lèi)型模型。
上述內(nèi)容就是ASP.NET MVC中怎么綁定數(shù)組模型,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。