2013-02-11 54 views
54

Nếu tôi muốn có một tập hợp các nguyên liệu đầu vào trong một hình thức liên kết với một List trong MVC 4, tôi biết rằng quy ước đặt tên sau cho inputname thuộc tính sẽ làm việc:Làm thế nào để MVC 4 List Model Binding hoạt động?

<input name="[0].Id" type="text" /> 
<input name="[1].Id" type="text" /> 
<input name="[2].Id" type="text" /> 

Nhưng tôi tò mò về cách tha thứ những chất kết dính mô hình là. Ví dụ: về những điều sau đây:

<input name="[0].Id" type="text" /> 
<input name="[3].Id" type="text" /> 
<input name="[8].Id" type="text" /> 

Trình kết nối mô hình xử lý việc này như thế nào? Nó có liên kết với một số List có chiều dài 9 bằng không? Hay nó vẫn liên kết với một số List có chiều dài 3? Hoặc nó sẽ bị nghẹt thở hoàn toàn?

Tại sao tôi quan tâm

Tôi muốn thực hiện một hình thức năng động trong đó người dùng có thể thêm hàng mẫu, và cũng có thể xóa các hàng từ biểu mẫu. Vì vậy, nếu tôi người dùng xóa hàng 2 trong tổng số 8 hàng, tôi muốn biết liệu tôi có cần phải đổi lại tất cả các đầu vào tiếp theo hay không.

+1

Hãy xem này: http://stackoverflow.com/questions/ 7807127/non-sequential-list-binding-not-working. Câu hỏi cho thấy một cú pháp cho ràng buộc không tuần tự (và câu trả lời xác nhận tính khả dụng của nó trong MVC2 và cao hơn). Tôi đã sử dụng nó nhân dịp. Như câu hỏi ban đầu của bạn: Nếu tôi nhớ lại chính xác, nó sẽ thất bại ... nhưng nó đủ dễ dàng để thử trước khi bạn bận tâm với hướng dẫn sử dụng lập chỉ mục, không tuần tự ràng buộc. –

+1

@TimMedora, Cảm ơn - không ràng buộc tuần tự là một phần thuật ngữ hữu ích mà tôi thiếu. – Eric

+4

Chủ đề đáng ngạc nhiên là không rõ ràng. Nếu bạn tìm kiếm xung quanh có một vài blog hay về chủ đề này, và cuốn sách này trình bày nó ở một trong các chương sau: http://www.amazon.com/Pro-ASP-NET-MVC-3-Framework/dp/1430234040 –

Trả lời

45

Có một định dạng dây cụ thể để sử dụng với các bộ sưu tập. Này được thảo luận trên Scott Hanselman của blog ở đây:

http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

Một blog entry từ Phil Haack nói về vấn đề này ở đây:

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Cuối cùng, một blog entry mà thực hiện chính xác những gì bạn muốn ở đây :

http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/

+0

Hoàn hảo, nhờ – Eric

+4

@shashwat - làm thế nào để đưa ra câu trả lời có hoặc không rõ ràng để mở các câu hỏi đã kết thúc trong đó câu trả lời không thể là có hoặc không? –

+1

@AnimalsAreNotOursToEat 'Làm thế nào để MVC 4 Danh sách mô hình ràng buộc làm việc?' ** Có ** – Jonesopolis

3

Tôi có danh sách động trông như thế này:

<ul id="okvedList" class="unstyled span8 editableList"> 
<li> 
    <input data-val="true" data-val-required="The Guid field is required." id="Okveds_0__Guid" name="Okveds[0].Guid" type="hidden" value="2627d99a-1fcd-438e-8109-5705dd0ac7bb"> 
    --//-- 
</li> 

vì vậy khi tôi thêm hoặc loại bỏ các hàng (yếu tố li) tôi phải sắp xếp lại các mục

this.reorderItems = function() { 
     var li = this.el_list.find('li'); 

     for (var i = 0; i < li.length; i++) { 
      var inputs = $(li[i]).find('input'); 

      $.each(inputs, function() { 
       var input = $(this); 

       var name = input.attr('name'); 
       input.attr('name', name.replace(new RegExp("\\[.*\\]", 'gi'), '[' + i + ']')); 

       var id = input.attr('id'); 
       input.attr('id', id.replace(new RegExp('_.*__', 'i'), '_' + i + '__')); 
      }); 
     } 
    }; 

danh sách này được đặt vào đơn giản Html.BeginTừ danh sách khách hàng và giống như Danh sách hoạt động trên serverside

1

Tôi cũng phải đối mặt với vấn đề tương tự trong quá khứ, và tôi sử dụng KnockoutJS để xử lý kịch bản như vậy.

Về cơ bản, Knockout gửi bộ sưu tập bằng chuỗi JSON và tôi đã deserialized chúng trong bộ điều khiển của mình.

Để biết thêm thông: http://learn.knockoutjs.com/#/?tutorial=collections

15

Tôi đã theo dõi pproach được liên kết trong các blog ở trên và thêm một vài chi tiết có thể hữu ích cho một số người - đặc biệt khi tôi muốn tự động thêm bất kỳ số hàng nào nhưng không muốn sử dụng AJAX để làm như vậy (tôi muốn biểu mẫu chỉ gửi trong bài đăng). Tôi cũng không muốn lo lắng về việc duy trì các id tuần tự.Tôi đã chiếm được một danh sách bắt đầu và ngày kết thúc:

Xem mẫu:

public class WhenViewModel : BaseViewModel { 
    public List<DateViewModel> Dates { get; set; } 
    //... Other properties 
} 

Start/End Date View mẫu:

public class DateViewModel { 
    public string DateID { get; set; } 
    public DateTime? StartDate { get; set; } 
    public DateTime? EndDate { get; set; } 
} 

Sau đó sử dụng chúng trong trang (với datepicker):

<div class="grid-8-12 clear" id="DatesBlock"> 
@{ 
    foreach (DateViewModel d in Model.Dates) { 
     @:<div class="grid-5-12 left clear"> 
      @Html.Hidden("Dates.Index", d.DateID) 
      @Html.Hidden("Dates[" + d.DateID + "].DateID", d.DateID) //ID again to populate the view model 
      @Html.TextBox("Dates[" + d.DateID + "].StartDate", 
          d.StartDate.Value.ToString("yyyy-MM-dd")) 
     @:</div> 
     @:<div class="grid-5-12"> 
      @Html.TextBox("Dates[" + d.DateID + "].EndDate", 
          d.EndDate.Value.ToString("yyyy-MM-dd")) 
     @:</div> 

     <script type="text/javascript"> 
      $('input[name="Dates[@d.DateID].StartDate"]') 
       .datepicker({ dateFormat: 'yy-mm-dd'}); 
      $('input[name="Dates[@d.DateID].EndDate"]') 
       .datepicker({dateFormat: 'yy-mm-dd'}); 
     </script> 
    } 
} 
</div> 
<a href="#" onclick="AddDatesRow()">Add Dates</a> 

Khi bài đăng trên blog được liên kết trong bài đăng @ErikTheVikings ở trên mô tả, bộ sưu tập được tạo bởi yếu tố ẩn lặp đi lặp lại: @Html.Hidden("Dates.Index", d.DateID) cho mỗi mục nhập trong bộ sưu tập trên trang.

Tôi muốn tùy tiện thêm hàng mà không cần sử dụng AJAX để gửi dữ liệu trở lại máy chủ mà tôi đã làm bằng cách tạo ra một div ẩn chứa một mẫu của một "hàng"/mục trong bộ sưu tập:

Hidden "Template "hàng:

<div id="RowTemplate" style="display: none"> 
    <div class="grid-5-12 clear"> 
     @Html.Hidden("Dates.Index", "REPLACE_ID") 
     @Html.Hidden("Dates[REPLACE_ID].DateID", "REPLACE_ID") 
     @Html.TextBox("Dates[REPLACE_ID].StartDate", "") 
    </div> 
    <div class="grid-5-12"> 
     @Html.TextBox("Dates[REPLACE_ID].EndDate", "") 
    </div> 
</div> 

Sau đó, sử dụng jQuery mà bắt chước mẫu, cung cấp một id ngẫu nhiên để sử dụng cho một hàng mới và gắn thêm hàng nhân bản hiện nay có thể nhìn thấy div chứa trên:

jQuery để hoàn tất quá trình:

<script type="text/javascript"> 
    function AddDatesRow() { 
     var tempIndex = Math.random().toString(36).substr(2, 5); 
     var template = $('#RowTemplate'); 
     var insertRow = template.clone(false); 
     insertRow.find('input').each(function(){ //Run replace on each input 
      this.id = this.id.replace('REPLACE_ID', tempIndex); 
      this.name = this.name.replace('REPLACE_ID', tempIndex); 
      this.value = this.value.replace('REPLACE_ID', tempIndex); 
     }); 
     insertRow.show(); 
     $('#DatesBlock').append(insertRow.contents()); 

     //Attach datepicker to new elements 
     $('input[name="Dates['+tempIndex+'].StartDate"]') 
      .datepicker({dateFormat: 'yy-mm-dd' }); 
     $('input[name="Dates['+tempIndex+'].EndDate"]') 
      .datepicker({dateFormat: 'yy-mm-dd' }); 
    } 
</script> 

dụ JSFiddle của kết quả: http://jsfiddle.net/mdares/7JZh4/

0

tôi có chút vấn đề, khi tôi sử dụng trình duyệt Chrome và nhấp vào nút quay lại, và tôi tìm thấy đầu vào với loại = "ẩn" khi các giá trị được đặt động không được Trình duyệt Chrome xử lý đúng cách.

có lẽ chúng ta có thể thay đổi thông tin

<input type="hidden" name="Detes.Index" value="2016/01/06" /> 

để

<div style="display: none"> 
    <input type="text" name="Detes.Index" value="2016/01/06" /> 
</div> 

Form hơn: Chrome doesn't cache hidden form field values for use in browser history http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

Các vấn đề liên quan