2013-07-12 36 views
5

Tôi có một lớp được gọi là CategoryModel, một trong những thuộc tính trong số đó là danh sách các đối tượng cùng loại. Vì vậy, CategoryModel.Categories là loại List<CategoryModel>.MVC EditorĐối với mô hình ràng buộc cho nhiều hình thức chỉnh sửa trên một trang

Trên trang chỉ mục danh mục, tôi hiển thị trình chỉnh sửa cho từng danh mục để người dùng có thể thay đổi bất kỳ tên danh mục nào mà không phải truy cập trang chuyên dụng để làm như vậy. Cũng giống như vậy:

<ul id="categories> 
    @Html.EditorFor(model => model.Categories) 
</ul> 

Và mẫu biên tập viên cho CategoryModel trông như thế này:

<li class="folder"> 
    @using (Html.BeginForm("Edit", "Category", new { id = Model.Key }, FormMethod.Post, new { @class = "ajaxoff"})) { 
     @Html.ValidationSummary(true) 
     @Html.HiddenFor(model => model.Key) 
     @Html.HiddenFor(model => model.ParentKey) 
     @Html.HiddenFor(model => model.Sequence) 
     @Html.HiddenFor(model => model.IncludeDeleted) 

     @Html.TextBoxFor(model => model.Name, null, new { @class = "catName" }) 
     @Html.ValidationMessageFor(model => model.Name) 

     <input type="submit" value="Save" class="icon save" /> 
    } 
</li> 

Vấn đề là tôi có nộp mẫu đơn không ràng buộc một cách chính xác đến Edit hành động của CategoryController:

[HttpPost] 
public ActionResult Edit(CategoryModel category) 
{ 
    // At this point all properties in category are null 
} 

Nếu tôi kiểm tra tên trên trường và hộp văn bản ẩn, chúng được gắn nhãn dựa trên vị trí của chúng trong danh mục hiện tại ory (ví dụ: Categories[0].Name). Tuy nhiên, nếu tôi tạo chế độ xem chỉnh sửa riêng, chúng chỉ được đặt tên theo tên trường (ví dụ: Name).

Tôi đã cố gắng thay đổi bộ điều khiển để chấp nhận một danh sách các Thể loại:

[HttpPost] 
public ActionResult Edit(List<CategoryModel> categories) 
{ 
    var category = categories.First(); 
} 

này hoạt động nếu tôi nộp hạng mục đầu tiên, nhưng không ai trong số những người khác (trong những trường hợp Categories là null).

Tôi cũng đã cố gắng thay đổi cách tôi hiển thị EditorFor tôi, bằng cách làm này:

<ul id="categories> 
    @foreach (var cat in Model.Categories) 
    { 
     @Html.EditorFor(model => cat); 
    } 
</ul> 

Những thay đổi tên trường là như nhau đối với từng loại (ví dụ như tất cả các tên loại được gọi là cat.Name), mà tôi tin là một bước đi đúng hướng.

Vậy làm cách nào để liên kết chính xác với bộ điều khiển của tôi? Tôi nhận ra rằng tôi có thể gửi toàn bộ danh mục gốc và sau đó lưu từng danh mục con, nhưng điều này có vẻ như một cách rất không hiệu quả để gửi một thay đổi duy nhất.

Trả lời

6

tôi khám phá ra làm thế nào để làm điều này. Có một tình trạng quá tải cho Html.EditorFor cho phép bạn chỉ định các htmlFieldName tài sản (tham số thứ ba trong ví dụ dưới đây):

@foreach (var cat in Model.Categories) 
{ 
    @Html.EditorFor(model => cat, null, ""); 
} 

này làm cho tất cả các tên trường mà không cần bất kỳ tiền tố và cho phép tôi gửi bất kỳ loại đơn thành công .

+1

Tôi đã làm điều này nhưng tôi vẫn nhận được [0] và [1] sau tên trường, làm thế nào bạn đối phó với điều đó? – Dennis

+1

Tôi không nhận được sự cố bạn mô tả. Nếu bạn đã sử dụng @ Html.EditorFor (model => model.Categories, null, "") thay vì vòng lặp ở trên, bạn sẽ nhận được [0] và [1] trước tên trường, tuy nhiên, bởi vì bạn đang chuyển mảng tới phương thức EditorFor thay vì một mô hình riêng lẻ. – Maloric

0

Hành động chỉnh sửa của bạn chấp nhận danh mục CategoryModel, do đó bạn cần phải đặt lại tiền tố mô hình cho ràng buộc đúng. Đối với điều này bạn cần phải tạo ra phương pháp mở rộng của riêng bạn cho HtmlHelper như thế này:

public class BeginHtmlScope : IDisposable 
    { 
     private readonly TemplateInfo templateInfo; 
     private readonly string previousHtmlFieldPrefix; 

     public BeginHtmlScope(TemplateInfo templateInfo, string htmlFieldPrefix) 
     { 
      this.templateInfo = templateInfo; 

      previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix; 
      templateInfo.HtmlFieldPrefix = htmlFieldPrefix; 
     } 

     public void Dispose() 
     { 
      templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix; 

     } 
    } 
    public static class MyHtmlExtensions 
    { 
     public static IDisposable BeginHtmlScope(this HtmlHelper html, string htmlFieldPrefix) 
     { 
      return new BeginHtmlScope(html.ViewData.TemplateInfo, htmlFieldPrefix); 
     } 
    } 

Và sau đó sử dụng nó bên trong mẫu soạn thảo của bạn:

@using (Html.BeginHtmlScope("")) 
{ 
    <li class="folder"> 
    @using (Html.BeginForm("Edit", "Category", new { id = Model.Key }, FormMethod.Post, new { @class = "ajaxoff"})) { 
     @Html.ValidationSummary(true) 
     @Html.HiddenFor(model => model.Key) 
     @Html.HiddenFor(model => model.ParentKey) 
     @Html.HiddenFor(model => model.Sequence) 
     @Html.HiddenFor(model => model.IncludeDeleted) 

     @Html.TextBoxFor(model => model.Name, null, new { @class = "catName" }) 
     @Html.ValidationMessageFor(model => model.Name) 

     <input type="submit" value="Save" class="icon save" /> 
    } 
</li> 

} 
+0

Thật không may điều này có cùng vấn đề với vòng lặp foreach - tên trường là Danh mục [0] .Name, Danh mục [1] .Name vv và CategoryModel không liên kết với hành động Chỉnh sửa. – Maloric

+0

Tôi xin lỗi vì đã hiểu nhầm câu hỏi của bạn. Tôi đã chỉnh sửa câu trả lời của mình. –

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