2013-03-20 39 views
5

Tổng quan: Tôi đang cố gắng sử dụng ViewModel có thuộc tính là lớp mô hình mà tôi đang cố chỉnh sửa . Tôi đã nhìn thấy công việc chỉnh sửa biểu mẫu bằng cách sử dụng biểu mẫu chỉnh sửa giàn giáo MVC khi chỉnh sửa mô hình trực tiếp, tuy nhiên tôi đang cố gắng sử dụng một ViewModel chứa mô hình đang được chỉnh sửa. Mọi thứ hoạt động ngoại trừ việc lưu một trường được hiển thị trong DropDownList.MVC 3: DropDownList trên Biểu mẫu chỉnh sửa cho đối tượng là thuộc tính của ViewModel

Giải thích: Tôi đã cố gắng sử dụng các tính năng giàn giáo của MVC 3 để tạo biểu mẫu chỉnh sửa cho mô hình. Trong hướng dẫn MVC Music Store, điều này được thực hiện cho trang Chỉnh sửa của Album, trong StoreManagerController. Trong trang đó, họ có hai trình đơn thả xuống cho Thể loại và Nghệ sĩ. Mỗi hình có vẻ tương tự như vậy trong chế độ xem: -

<div class="editor-label"> 
    @Html.LabelFor(model => model.GenreId, "Genre") 
</div> 
<div class="editor-field"> 
    @Html.DropDownList("GenreId", String.Empty) 
    @Html.ValidationMessageFor(model => model.GenreId) 
</div> 

Theo như tôi có thể biết, các tùy chọn này được điền vào bộ điều khiển bằng cách sử dụng ViewBag.

ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId); 
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId); 

Làm việc với mô hình trực tiếp

Trong mã của tôi, tôi cố gắng làm điều tương tự với một đối tượng mà đang được lưu vào DB thông qua Entity Framework.

Mẫu

public class Season 
{ 
    public int SeasonId { get; set; } 
    public int ClubId { get; set; } 
    public Club Club { get; set; } 
} 

Mã trong điều khiển

ViewBag.ClubId = new SelectList(clubs, "ClubId", "Name", season.ClubId); 

Xem

<div class="editor-label"> 
    @Html.LabelFor(model => model.ClubId, "Club") 
</div> 
<div class="editor-field"> 
    @Html.DropDownList("ClubId", String.Empty) 
    @Html.ValidationMessageFor(model => model.ClubId) 
</div> 

này hoạt động tốt.

Làm việc với View Mẫu

Tuy nhiên bây giờ tôi đã nhận ra rằng trang cần thêm văn bản hiển thị so với những gì có sẵn trong mô hình tôi chỉnh sửa. Tôi đã hy vọng tạo một Mô hình xem đặc biệt, với mô hình đã chỉnh sửa (phần) và văn bản bổ sung mà tôi muốn hiển thị.

ViewModel

public class EditSeasonViewModel 
{ 
    public string PlayerName {get; set;} 
    public string SummaryText {get; set;} 
    public int PlayerId {get; set;} 
    public Season season {get; set;} 
} 

Tôi đã làm điều này, thay đổi bộ điều khiển để có những phương pháp HttpGet và HttpPost sử dụng ViewModel mới, thay đổi View để chấp nhận các ViewModel mới, và thay đổi phương pháp tất cả 'EditorFor' trong xem để sử dụng model.season.MyProperty.

Mã trong điều khiển

ViewBag.ClubId = new SelectList(clubs, "ClubId", "Name", seasonVM.season.ClubId); 

Mã trong Xem

<div class="editor-label"> 
    @Html.LabelFor(model => model.season.ClubId, "Club") 
</div> 
<div class="editor-field"> 
    @Html.DropDownList("ClubId", String.Empty) 
    @Html.ValidationMessageFor(model => model.season.ClubId) 
</div> 

Khi gỡ lỗi các phương pháp HttpPost, tất cả các giá trị cho mùa đúng cách tồn tại, ngoại trừ cho giá trị ClubId mà phải xuất phát từ DropDropList .

Tôi chưa thay đổi DropDownList trong Chế độ xem ở tất cả từ cách thức khi chúng tôi sử dụng Mô hình trực tiếp.

Câu hỏi: Câu hỏi của tôi là, những gì tôi cần phải thay đổi để có được sự ClubId để được cứu đúng cách khi sử dụng mới EditSeasonViewModel này?

Ngoài ra, làm thế nào để ViewBag.ClubId trong phương pháp HttpGet trong bộ điều khiển phù hợp với DropDownList trong dạng xem, và sau đó có giá trị của nó được truyền lại cho phương thức HttpPost?

Trả lời

9

Đó là tuyên bố DropDownList của bạn không chính xác. Hãy thử điều này thay vì:

@Html.DropDownListFor(m => m.season.ClubId, ViewBag.ClubId) 

Nhưng thực sự, bạn nên đặt rằng danh sách lựa chọn trong mô hình của bạn:

public SelectList Clubs { get; set; } 

Sau đó cư nó trong điều khiển của bạn:

Model.Clubs = new SelectList(clubs, "ClubId", "Name", season.ClubId); 

Sau đó, bạn có thể làm:

@Html.DropDownListFor(m => m.season.ClubId, Model.Clubs) 
+2

+1 cho việc sử dụng các helper mạnh mẽ gõ. Phần lớn các câu hỏi trong danh sách thả xuống trong [tag: asp.net-mvc] là kết quả của việc bị rối tung lên trong ViewBag, những người trợ giúp bị đánh máy yếu và những tai ương liên quan đến mô hình. –

+0

@SeanHolmesby Cảm ơn bạn đã chỉnh sửa :) – mattytommo

+0

@mattytommo - Tuyệt vời. Điều đó hiệu quả. Tôi đã đi trước và sử dụng helper mạnh mẽ đánh máy của bạn, trong đó, từ những gì Forty-Two nói, là một cách tốt hơn để đối phó với danh sách thả xuống. Tôi nghĩ rằng tôi hiểu quá trình của nó tất cả bây giờ. –

3

Tránh sử dụng các công cụ động như ViewBag/ViewData để chuyển dữ liệu từ phương thức hành động sang chế độ xem. Chuyển sang phương pháp gõ mạnh mẽ.

Cập nhật ViewModel của bạn để có thêm 2 thuộc tính. một để tổ chức một bộ sưu tập các câu lạc bộ có sẵn và một để giữ câu lạc bộ được chọn.

public class EditSeasonViewModel 
{ 
    public List<SelectListItem> Clubs { set;get;} 
    public int SelectedClub { set;get;} 

    public string PlayerName {get; set;} 
    public string SummaryText {get; set;} 
    public int PlayerId {get; set;} 
    public Season season {get; set;} 

    public EditSeasonViewModel() 
    { 
     Clubs=new List<SelectListItem>(); 
    } 
} 

Bây giờ trong hành động GET, Tải các câu lạc bộ và tải nó lên thuộc tính Clubs.

public ActionResult create(int id) 
{ 
    var vm=new EditSeasonViewModel(); 
    vm.Clubs=GetListOfSelectListItemFromClubsFromSomeWhere(); 
    return View(vm); 
} 

giả GetListOfSelectListItemFromClubsFromSomeWhere là một phương pháp mà trả về một danh sách các SelectListItem cho câu lạc bộ của bạn

public List<SelectListItem> GetListOfSelectListItemFromClubsFromSomeWhere() 
{ 
    // to do : return List<SelectListItem> with Value and Text(ClubId Id & Name) 
} 

và theo quan điểm của bạn, sử dụng phương pháp Html.DropDownListFor helper

@model EditSeasonViewModel 
@using(Html.Beginform()) 
{ 

    @Html.DropdownlistFor(x=>x.SelectedClub, 
          new SelectList(Model.Clubs,"Value","Text"),"select") 
    <input type="submit" /> 
} 

Khi hình thức này đang được được đăng, bạn sẽ nhận được id của câu lạc bộ đã chọn trong thuộc tính SelectedClub của mô hình đã đăng của bạn.

0

Hãy chắc chắn rằng trong bộ điều khiển chỉnh sửa/hành động creat của bạn, tài sản được binded một cách chính xác:

public async Task<ActionResult> Edit([Bind(Include = "SeasonId,ClubId, otherproperties"]){ 
// code ... 
} 
Các vấn đề liên quan