2016-03-14 18 views
5

Tôi là một nhà phát triển phần mềm .NET C# có kinh nghiệm, tuy nhiên chỉ một vài tháng trước, tôi bắt đầu làm việc với MVC Razor (MVC 5).MVC Razor tạo danh sách các đối tượng để gửi

Tôi có một tình huống nhỏ mà tôi không thể tìm thấy bất kỳ câu trả lời cho trên mạng (sau giờ tìm kiếm)

Tôi có một mô hình mà có một danh sách các mẫu khác do đó cũng có một danh sách các một mô hình như hình dưới đây.

public class Parent 
{ 
    public string Name { get; set; } 
    public string Sex { get; set; } 
    public int Age { get; set; } 
    public List<Child> Children { get; set; } 
} 

public class Child 
{ 
    public string Name { get; set; } 
    public string Sex { get; set; } 
    public int Age { get; set; } 
    public List<GrandChild> GrandChildren { get; set; } 
} 

public class GrandChild 
{ 
    public string Name { get; set; } 
    public string Sex { get; set; } 
    public int Age { get; set; } 
} 

và điều khiển của tôi có 2 phương pháp, một là chính Nhận, và một trong những khác là bài để gửi dữ liệu mới

public ActionResult Index() 
{ 
    return View(); 
} 

[HttpPost] 
public ActionResult PostParent(Parent parent) 
{ 
    if (ModelState.IsValid) 
    { 
     //Do an insert to the DB 
     return View("~/Views/Home/Index.cshtml"); 
    } 

    return Json("Error"); 
} 

Tuy nhiên, trong quan điểm của tôi trong Mẫu, tôi không thể tìm thấy một cách để tạo ra một nút add và chèn dữ liệu mới vào danh sách các con và cháu (trong trường hợp của một trẻ em)

@using (Html.BeginForm("PostParent", "Home", FormMethod.Post, new {@class = "form-horizontal", role = "form"})) 
{ 
    @Html.LabelFor(x => x.Name) 
    @Html.TextBoxFor(x => x.Name) 
} 

tôi chỉ có thể thêm các trường cho properites kiểu nguyên thủy, nhưng không phải cho các đối tượng.

Tôi thực sự đánh giá cao bất kỳ Trợ giúp nào!

+0

Tham khảo câu trả lời [tại đây] (http://stackoverflow.com/questions/29161481/post-a-form-array-without-successful/29161796#29161796) và [tại đây] (http://stackoverflow.com/questions/28019793/submit-same-partial-view-gọi-nhiều lần-dữ liệu-to-controller/28081308 # 28081308). Lưu ý rằng bạn không thể sử dụng 'BeginCollectionItem' cho các bộ sưu tập lồng nhau –

+0

Và để có ví dụ làm việc về việc tạo các bộ sưu tập lồng nhau, hãy tham khảo [DotNetFiddle] (https://dotnetfiddle.net/wqE6Rb) –

Trả lời

2

Tôi nghĩ bạn cần một tiêu chuẩn thông thường <input/> mà bạn nên biết từ HTML5. Nếu tôi hiểu chính xác bạn, bạn muốn chuyển dữ liệu từ chế độ xem tới Bộ điều khiển. Bây giờ bạn cần một nút trong biểu mẫu bạn đã tạo. Bạn cần/nên gọi một Bộ điều khiển bằng cách truyền dữ liệu mô hình từ khung nhìn đến Bộ điều khiển. @Html.ActionLink() là một Razor-Helper cho <Input>

Something như thế này bên trong hình thức thể nên làm như lừa:

@Html.ActionLink("Click here to pass", "ActionName", new { ParameterNameOfTheController = Model }) 

Logic đằng sau những thứ mà nên xảy ra trong điều khiển. Tôi hy vọng điều này có thể giúp bạn.

+0

Hi H. Senkaya Có tôi đã có nút gửi, và logic là trong bộ điều khiển, tuy nhiên, tôi đang tự hỏi làm thế nào để tạo danh sách mới và thêm các mục vào danh sách từ xem, vì vậy khi tôi bấm gửi, dữ liệu sẽ có. –

2

Tôi đã thực hiện một dự án liên quan đến kịch bản của bạn. Tuy nhiên, tôi không thể tìm thấy một giải pháp dao cạo. Vì vậy, tôi đã kết thúc bằng cách sử dụng plugin SheepIt jquery để tự động thêm các trường.

https://github.com/mdelrosso/sheepit

Hãy chắc chắn rằng bạn dính vào id và tên mẫu mà asp mvc hiểu.

<input class="form-control text-box single-line" id="sheepItForm_#index#__Field" name="sheepItForm[#index#].Field" type="text" value="" /> 
 
<span class="field-validation-valid text-danger" data-valmsg-for="sheepItForm[0].Field" data-valmsg-replace="true"></span>

Hope this helps!

+0

Hi Vish J Tôi thực sự đã tìm thấy một giải pháp bằng cách thêm các mục vào danh sách bằng cách sử dụng javascript tinh khiết và gắn bó với các mẫu đặt tên mvc. Nhưng điều này sẽ mất quá nhiều thời gian nếu bạn có các đối tượng lồng nhau phức tạp. –

7

Đối với điều này bạn có thể sử dụng Html.BeginCollectionItemhttps://www.nuget.org/packages/BeginCollectionItem/

Những gì bạn có thể làm là có một Xem cho Form chính và Vượt qua Parent mẫu để nó như thế này sẽ đại diện cho phụ huynh, sau đó bạn sẽ cần một hàng để đại diện cho Trẻ em, bạn có thể gọi số này là ChildRow.cshtml

Vì vậy, đối với Phụ huynh, chúng tôi đang tạo Create.cshtml Xem chúng tôi sẽ vượt qua Mô hình chính.

@model Parent 

@using(Html.BeginForm()) 
{ 
    @Html.TextBoxFor(m => m.Name) 


    <table id="children"> 
     <tbody> 

<!-- This here will display the Child Row for existing Rows in the Parent model --> 

      @foreach (var child in Model.Children) 
      { 
       @Html.Partial("ChildRow", child) 
      } 
     </tbody> 

    </table> 
<button type="button" id="addChild">Add Child</button> 

<button type="submit"> Save</button> 
    } 

Sau đó, đây là những gì ChildRow.cshtml sẽ trông như thế, Nó sẽ có mô hình Child.

Lưu ý: bạn sẽ phải thêm thuộc tính IsDeleted vào Mô hình con, điều này sẽ giúp bạn trong bộ điều khiển - để xem liệu Trẻ có bị xóa hay Không.

@model Child 

@using (Html.BeginCollectionItem("Children")) 
{ 
    <tr> 
     <td> 
      @Html.HiddenFor(m => m.IsDeleted, new { data_is_deleted = "false" }) 
      @Html.HiddenFor(m => m.ChildId) 
      @Html.TextBoxFor(m => m.Name) 
     </td> 

     <td> 
      <span class="glyphicon glyphicon-trash action-icon" data-action="removeItem"></span> 
     </td> 


    <tr> 
} 

Bây giờ bạn phải thêm hàng vào cuối bảng khi nút Add Child được nhấp.

Đối với điều này bạn sẽ tạo ra một hành động mới trong Bộ điều khiển:

public ActionResult AddChild() 
    { 
     return PartialView("Child", new Child()); 
    } 

Và sau đó thêm jQuery này đến Create.cshtml

$("#addChild").on("click", function() { 
     $.ajax({ 
      url: '@Url.Action("AddChild", "YourController")' 
     }).success(function (partialView) { 
      $('#children> tbody:last-child').append(partialView); 
     }); 
    }); 

này sẽ nối thêm một Row trẻ em mới đến Bảng

Ngoài ra, bạn sẽ phải ẩn/tắt hàng nếu bạn muốn xóa trên cùng một trang, vì vậy bạn có thể thêm jQuery này:

$('body').on("click", '*[data-action="removeItem"]', function (e) { 
    e.stopPropagation(); 
    var btn = $(this); 
    var row = btn.closest('tr'); 
    var firstCell = $(row.find('td')[0]); 
    var checkBox = firstCell.find('*[data-is-deleted]'); 
    var checkBoxVal = checkBox.val(); 

    if (checkBoxVal === 'False' || checkBox.val() === 'false') { 
     checkBox.val('true'); 
     row.find('td').find('input, textarea, select').attr('readonly', 'readonly'); 
    } else { 
     checkBox.val('false'); 
     row.find('td').find('input, textarea, select').attr("readonly", false); 
    } 

}); 

Sau đó, khi bạn ĐĂNG lại cho Bộ điều khiển, bạn sẽ thấy Danh sách trẻ em trong Mô hình.

[HttpPost] 
public ActionResult Create(Parent model) 
{ 

    var newChildren = model.Children.Where(s => !s.IsDeleted && s.ChildId == 0); 

    var updated = model.Children.Where(s => !s.IsDeleted && s.ChildId != 0); 

    var deletedChildren = model.Children.Where(s => s.IsDeleted && s.ChildId != 0); 


    return View(model); 
} 

Bạn sẽ phải làm điều gì đó tương tự cho Cháu.

+1

Wow, điều đó thực sự hiệu quả, cảm ơn ví dụ của bạn bây giờ tôi có một sự hiểu biết tốt hơn về cách sử dụng Html.BeginCollectionItem. Được đánh dấu là câu trả lời :) –

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