ASP.NET MVC 基於強類型視圖下 對模型以及模型中List 字段的同時編輯 表單提交


第一次發文章,排版上簡單粗糙了些。如果內容中有什么錯誤之處,歡迎指正。相互學習,共同提高。

本人受http://shiyousan.com/post/635383025861004585  此文啟發。尊重原創。

大多數時候我們提交的web表單內容都是之前就決定好的。

比如在 csdn 個人主頁中編輯簡介的時候看到的表單。

 

這樣的表單是固定的,因為它足夠簡單,而且被擴展的可能性也不大。

但是你總會遇到一些讓你頭疼的需求。

不多廢話,我們直接進主題。

假如我們有一個實體類A,A中有一個屬性 List<B> Member。

代碼如下:   

 1     public class Dept
 2 
 3     {
 4 
 5         public int Id { get; set; }
 6 
 7         public string Name { get; set; }
 8 
 9         public string Description { get; set; }
10 
11         public List<Employee> Members {get; set; }
12 
13     }
14 
15  
16 
17     public class Employee
18 
19     {
20 
21         public int Id { get; set; }
22 
23         public string Name { get; set; }
24 
25         public int Age { get; set; }
26 
27     }
View Code

 

我們希望在編輯Dept的時候也可以同時編輯Members中的各個子集Employee。

我們先在Dept控制器中創建Index方法,並在其中初始化一點測試數據。具體如下:

 1 public class DeptController : Controller
 2 
 3 {
 4 
 5     public ViewResult Index()
 6 
 7     {
 8 
 9         var dept = new Dept() {
10 
11             Id = 1,
12 
13             Name = "First Dept",
14 
15             Description = string.Empty,
16 
17             Members = newList<Employee>()
18 
19         };
20 
21         dept.Members.Add(new Employee() {
22 
23             Id = 1,
24 
25             Name = "犀利的綿羊",
26 
27             Age = 24
28 
29         });
30 
31         return View(dept);
32 
33     }
34 
35  
36 
37     [HttpPost]
38 
39     public ActionResult Index(Dept dept)
40 
41     {
42 
43         var membersCount = dept.Members.Count;
44 
45         var t = dept;
46 
47         return Json("done",JsonRequestBehavior.DenyGet);
48 
49     }
50 
51 }
View Code

 

接下來我們創建Index視圖,我們可以看到Index方法中的視圖模型是Dept類,在Index視圖起始位置寫上@model Dept(注意:如果運行出錯,可以在Dept之前加上完整的命名空間,也可以在Views目錄下的web.config文件中添加命名空間,類似<addnamespace="YourNamespace" />)

 1 @modelDept
 2 
 3  
 4 
 5 @using(Html.BeginForm())
 6 
 7 {   
 8 
 9     <div>
10 
11         <table >
12 
13             <caption>部門信息</caption>
14 
15             <tr>
16 
17                 <td>名稱</td>
18 
19                <td>@Html.TextBoxFor(x=>x.Name)</td>
20 
21             </tr>
22 
23             <tr>
24 
25                 <td>描述</td>
26 
27                <td>@Html.TextBoxFor(x=>x.Description)</td>
28 
29             </tr>
30 
31             <tr>
32 
33                 <td>成員</td>
34 
35                 <td>
36 
37                     <ul>
38 
39                         @for(var i = 0; i <Model.Members.Count; i++)
40 
41                         {
42 
43                             <li>
44 
45                                 姓名:@Html.TextBoxFor(x=>x.Members[i].Name)
46 
47                                 年齡:@Html.EditorFor(x=>x.Members[i].Age)
48 
49                                 <inputtype="button" value="刪除" class="deleteMember" />
50 
51                             </li>
52 
53                         }
54 
55                     </ul>
56 
57                 </td>
58 
59             </tr>
60 
61         </table>
62 
63     </div>
64 
65     <input type="submit"value="保存"/>
66 
67 }
View Code

我們可以看到,在處理Members時,我們用到了for循環和Html輔助方法。

生成的姓名和年齡對應的文本框的id和name屬性都會包含for循環中 i 的值,也就是下標。截圖如下:

 

下圖是生成的頁面

 

接下來就是前端的工作了,js代碼如下:

  1 $(function() {
  2 
  3     init();
  4 
  5 })
  6 
  7  
  8 
  9 function init() {
 10 
 11     $(".addMember").remove();
 12 
 13    $(".deleteMember").last().after("<input type='button'value='添加' class='addMember'/>");
 14 
 15     initAddBtn();
 16 
 17     initDeleteBtn();
 18 
 19 }
 20 
 21  
 22 
 23 function initDeleteBtn() {
 24 
 25     $(".deleteMember").unbind();
 26 
 27     $(".deleteMember").click(function() {
 28 
 29         var memberCount =$(".deleteMember").length;
 30 
 31         if (memberCount <= 1) {
 32 
 33             alert("溫馨提示:至少得有一個員工哦");
 34 
 35             return false;
 36 
 37         }
 38 
 39  
 40 
 41         // 修改當前員工下方的所有員工的可編輯框的屬性(id, name)
 42 
 43        $(this).parents("li").nextAll().each(function () {
 44 
 45             // 獲取輸入框
 46 
 47             var txts =$(this).children("input[type='text'], input[type='number']");
 48 
 49             // 獲取當前員工name屬性中的數字,也就是 Members 屬性的下標
 50 
 51             var index =Number(txts.eq(0).attr("name").match(/\d+/)[0]);
 52 
 53             txts.each(function () {
 54 
 55                 // 修改屬性中的數字的值, 當前員工下標 -1
 56 
 57                 $(this).attr("id",$(this).attr("id").replace(/\d+/, index - 1));
 58 
 59                 $(this).attr("name",$(this).attr("name").replace(/\d+/, index - 1));
 60 
 61             })
 62 
 63         })
 64 
 65         // 刪除當前 li 標簽
 66 
 67        $(this).parents("li").remove();
 68 
 69         init();
 70 
 71     });
 72 
 73 }
 74 
 75 function initAddBtn() {
 76 
 77     $(".addMember").unbind();
 78 
 79     $(".addMember").click(function (){
 80 
 81         // 復制當前 li 標簽,並添加到當前 li 標簽后面,形成添加效果
 82 
 83         var parent =$(this).parents("li").clone();
 84 
 85        $(this).parents("li").after(parent);
 86 
 87  
 88 
 89         // 清空復制項的各個編輯框
 90 
 91         var txts =parent.children("input[type='text'], input[type='number']");
 92 
 93         txts.val("");
 94 
 95  
 96 
 97         // 獲取復制項中“姓名”框的name屬性中的數字,也就是 Members 屬性的下標
 98 
 99         var index =Number($(this).siblings().eq(0).attr("name").match(/\d+/)[0]);
100 
101         txts.each(function () {
102 
103             // 新增的員工的 Member 下標 +1
104 
105             $(this).attr("id",$(this).attr("id").replace(/\d+/, index + 1));
106 
107             $(this).attr("name",$(this).attr("name").replace(/\d+/, index + 1));
108 
109         })
110 
111         // 刪除當前 “添加” 按鈕
112 
113         $(this).remove();
114 
115         init();
116 
117     })
118 
119 }
View Code

 

需要注意的是“添加”和“刪除”按鈕的點擊事件的處理邏輯(就好像操作List一樣,刪除List中的一個元素,則后方的所有元素的下標要-1, 添加的元素在尾部,其下標值是List.Count - 1)。

當我們提交這個表單的時候,Dept的其他字段不用特別在意,但是Members字段的所有下標不能間斷,且需從0開始,依次遞增。

下面附上調試截圖為依據:(生成的html不太好看,下圖中的html是經過調整的)

 

點擊“保存”,然后我們可以看到如下的調試信息,此時的dept.Members有三個元素。而且各個元素的屬性與填寫的表單內容一致。

 

 

現在我們修改一下html中的一部分,再看看操作操作結果:

 

我們可以看到第三個元素的下標改成了3,形成了0,1,3 的不連續的情況。點擊“保存”,我們看調試信息:

 

我們可以看到只接收到前兩個元素。不連續的第三個元素已經丟失。

我們再看看第一個元素下標不為零的情況:

 

 

可以看到Members沒有接收到任何元素。

現在我們證實了上面的觀點。

 

下面我們來引申一下,如果我們試圖的模型是List<Employee>而不是Dept,我們是不是也可以用這種方法做到多個元素同時編輯?我想應該是沒問題的。不用那些JS插件,我們一樣可以實現行內編輯哦。

 


免責聲明!

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



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