2010-07-28 12 views
5

Tôi có điều này để điền một danh sách thả xuống trong chế độ xem ASP.NET MVC.ASP.NET MVC: DropDownListFor không chọn bất kỳ tùy chọn

<%= Html.DropDownListFor(model => model.Bikes, 
     Model.Bikes.Select(
     x => new SelectListItem { 
       Text = x.Name, 
       Value = Url.Action("Details", "Bike", new { bikeId = x.ID }), 
       Selected = x.ID == Model.ID, 
      })) %> 

Gỡ rối này, tôi có thể thấy rằng Selected tài sản được thiết lập để true khi nó phải được. Nhưng khi khung nhìn được hiển thị, không có tùy chọn nào trong danh sách được chọn. Tôi nhận ra rằng điều này có thể được thực hiện với một tình trạng quá tải khác của DropDownListFor nhưng tôi thực sự muốn phiên bản này hoạt động.

Bất kỳ ý tưởng nào?

Trả lời

5

Lý do giá trị đã chọn của bạn không hoạt động là vì bạn đang sử dụng Url làm giá trị tùy chọn nhưng chỉ định Model.ID trong mệnh đề Selected.

Hãy thử như thế này:

<%= Html.DropDownListFor(
    model => model.Bikes, 
    new SelectList(Model.Bikes, "Id", "Name", Model.ID) 
)%> 

"Id" chỉ ra tài sản đó sẽ được sử dụng như giá trị tùy chọn trong khi "Name" chỉ ra tài sản đó sẽ được sử dụng như lựa chọn nhãn.

Nếu bạn muốn giữ gìn Url.Action bạn có thể thử:

<%= Html.DropDownListFor(
    model => model.Bikes, 
    new SelectList(Model.Bikes.Select(x => new { 
     Id = x.Id, 
     Name = Url.Action("Details", "Bike", new { bikeId = x.ID }) 
    }), "Id", "Name", Model.ID) 
)%> 

Bạn sẽ nhận thấy rằng tôi đã đảo ngược tên và Id vì nó có vẻ hợp lý hơn để sử dụng các mô hình Id như giá trị tùy chọn.


UPDATE:

Lý do này không hoạt động là bởi vì bạn đang liên kết với một IEnumerable (đối số đầu tiên của DropDownListFor helper). Nó phải là thuộc tính vô hướng trong khi bạn đang sử dụng cùng một bộ sưu tập model.Bikes:

<%= Html.DropDownListFor(
    model => model.SelectedBikeValue, 
    Model.Bikes.Select(
     x => new SelectListItem { 
       Text = x.Name, 
       Value = Url.Action("Details", "Bike", new { bikeId = x.ID }), 
       Selected = x.ID == Model.ID, 
     } 
)) %> 

Nhận xét của tôi về việc không sử dụng các url làm giá trị tùy chọn là đúng.

+0

Lưu ý rằng trong câu hỏi ban đầu, giá trị là URL. –

+1

Có, tôi đã nhận thấy điều này, nhưng vì điều này dường như với tôi một ý tưởng tồi tôi đã đảo ngược chúng. Bằng cách đó là lý do tại sao giá trị bạn chọn không hoạt động. Bạn đang chuyển Model.Id dưới dạng giá trị đã chọn và sử dụng url làm giá trị tùy chọn. Không tốt.Tôi khuyên bạn nên giữ nguyên ID làm giá trị tùy chọn và nếu cần tìm nạp URL tương ứng trong hành động của trình điều khiển bạn đang gửi. Tôi không thấy hợp lý khi sử dụng url làm giá trị tùy chọn. –

+0

Trong mã ban đầu của tôi, tôi không chuyển ID như các giá trị và URL đã chọn làm giá trị tùy chọn. Những gì tôi đang làm là đặt các giá trị thành URL và sau đó sử dụng điều kiện cần giữ cho mục sẽ được chọn. Và có thực sự bất kỳ lý do thuyết phục nào về lý do tại sao tôi không nên sử dụng URL cho các giá trị không? –

0

Tôi đã gặp rất nhiều rắc rối với khái niệm này. Nó đặc biệt thể hiện chính nó khi bạn không thể vượt qua nó "tên" thuộc tính từ mô hình có chứa thuộc tính đó trong một đối tượng, vì tên đối tượng đó được tự động thêm vào tên. Điều này là điên. Sau khi lãng phí nhiều giờ cố gắng để con số này ra tôi chỉ cần bỏ và viết phần mở rộng thả xuống của riêng tôi mà tôi xuất bản ở đây. Nó rất đơn giản và nó hoạt động tốt.

public static MvcHtmlString SimpleDropDown(this HtmlHelper helper, object attributes, IEnumerable<SelectListItem> items, bool disabled = false) 
    { 
     XElement e = new XElement("select", 
      items.Select(a => { 
       XElement option = new XElement("option", a.Text); 
       option.SetAttributeValue("value", a.Value); 
       if (a.Selected) 
        option.SetAttributeValue("selected", "selected"); 
       return option; 
      }) 
      ); 

     if (attributes != null) 
     { 
      Dictionary<string, string> values = (from x in attributes.GetType().GetProperties() select x).ToDictionary(x => x.Name, x => (x.GetGetMethod().Invoke(attributes, null) == null ? "" : x.GetGetMethod().Invoke(attributes, null).ToString())); 
      foreach(var v in values) 
       e.SetAttributeValue(v.Key, v.Value); 
     } 

     if (disabled) 
      e.SetAttributeValue("disabled", ""); 

     return new MvcHtmlString(e.ToString()); 
    } 

Ngoài ra, tôi đưa lá cờ tàn tật như một tham số phụ, bởi vì nếu bạn muốn liên kết với nó thông qua danh sách nặc danh tiêu chuẩn của các thuộc tính, nó có thể khá phức tạp.

Dưới đây là ví dụ về cách tôi sử dụng tại thời điểm này. Tôi dịch từ điển sang danh sách SelectListItem, nhưng nó có thể chỉ là một danh sách đơn giản.

@Html.SimpleDropDown(new { id="EOM", name = "EOM", @class = "topBox" }, Model.EOM.Select(x => new SelectListItem { Text = x.Value, Value = x.Key.ToString(), Selected = Model.EOM.Selected == x.Key }), !Model.EOM.Available)