Asp.net-Mvc-3

添加屬性以選擇列表選項

  • July 1, 2012

我在 Razor 視圖的下拉列表中有一個項目列表。在數據庫中,每個項目都有 3 個與之關聯的值 - 數據庫 ID、短名稱(用於顯示)和長名稱(用於傳遞給服務)。下拉列表必須顯示短名稱,因此我使用數據庫 id 作為值和短名稱作為文本填充下拉列表。

但是,當使用者選擇一個項目時,我需要將長名稱作為查詢參數傳遞給使用 jQuery 的搜尋服務,例如,當 Cortina 被選中時,需要將“Ford Cortina 1979 Blue”傳遞給該服務。我的第一個想法是將長名稱儲存為數據破折號屬性,但我想知道是否有更好的方法。所以

  • 如何將所有 3 個值儲存在下拉列表中?
  • 如果我確實使用數據破折號屬性,我如何將所有 LONG_NAME 值合併到 Html.DropDownListFor 或以某種方式將它們添加到下拉列表中?

D B:

CARID SHORT_NAME LONG_NAME
1     Viper     Dodge Viper 1982
2     Boxster   Porsche Boxster 2009 Black
3     Cortina   Ford Cortina 1979 Blue

控制器助手創建下拉菜單:

public static IEnumerable<SelectListItem> GetSelectList(this IEFRepository repository, string typeName)
{
   var vehicle = repository.TypeTypes.FirstOrDefault(t => t.Name.ToUpper() == typeName);
   if (vehicle != null)
   {
       var carList = vehicle.SubTypes.ToList().OrderBy(s => s.Name);
       var selectList = new SelectList(subTypeList, "SubTypeID", "Name");

       return selectList;
   }
}

這是我用來創建下拉菜單的程式碼:

<div class="editor-field">
   @Html.DropDownListFor(model => model.CarID,
       new SelectList(ViewBag.Cars, "Value", "Text", "1"))
   @Html.ValidationMessageFor(model => model.CarShortName)
</div>

這是輸出:

<select id="CarID" name="CarID" data-val="true" data-val-number="The field CarID must be a number." data-val-required="The CarID field is required.">
   <option value="2">Boxster</option>
   <option value="3">Cortina</option>
   <option selected="selected" value="1">Viper</option>
</select>

現在才回到這個話題。雖然@nikeaa 的答案肯定是一個可行的解決方案,但我認為它有點重量級,尤其是使用 XDocument。提醒一下,我正在處理的是 TypeType(汽車)和 SubType(汽車類型列表 - Viper、Granada、Hunter、Zodiac、Wolsley 1660 等)。TypeType 也可以是 Trucks、Bicycles 等。這就是我解決它的方法:

我在 Controller 上添加了一個 JsonResult 方法來返回一個具有我想要的 3 個屬性的匿名對象:

public class VehicleController : Controller
{
   // etc.
   public JsonResult GetSubTypesForTypeType(string typeTypeName)
   {
       var cars = pronova2Repository.GetTypeWithSubTypes(typeTypeName);

       return cars == null
       ? Json(new object[0], JsonRequestBehavior.AllowGet)
       : Json(cars.SubTypes.OrderBy(s => s.Name).Select(
           s => new { s.SubTypeID, s.Name, s.Description }).ToArray(),
           JsonRequestBehavior.AllowGet);
   }
   // etc.
}

然後在js中:

填充下拉列表:

// populate the cars drop down when the select list is available
if ($('select#SubTypeID').length) {
   var carsSelect = $('select#SubTypeID');
   var carsList = populateCarsList("CARS");
   var carsListHtml = createCarsSelectList(carsList);
   carsSelect.html('');
   carsSelect.append(carsListHtml);

   $('#SubTypeID').change(function (e) {
       clearFormData();
   });
}

通過 ajax 呼叫呼叫函式以獲取子類型(汽車):

function populateCarsList(typeTypeName) {
   var carsList;

   $.ajax({
       url: '/Vehicle/GetSubTypesForTypeType',
       data: { typeTypeName: typeTypeName },
       async: false
   }).done(function (data) {
       carsList = data;
   }).error(function (msg, url, line) {
       alert("Error retrieving cars from Vehicle/GetSubTypesForTypeType. Error message: " + line);
   });

   return carsList;
}

使用添加的描述作為“data-*”屬性創建選擇列表的函式:

function createCarsSelectList(selectData) {
   var html = '',
       len = selectData.length,
       selected,
       description;

   for (var i = 0; i < len; i++) {

       // "Viper" should be selected by default
       if (selectData[i].Name.toLocaleUpperCase() === "VIPER") {
           selected = ' selected="selected" ';
       } else {
           selected = '';
       }

       // Add the description (as a "data-" attribute), some descritions are null
       if (selectData[i].Description != null) {
           description = selectData[i].Description;
       } else {
           description = '';
       }

       html += '<option value="' + selectData[i].SubTypeID + '" data-description="' + description + '"' + selected + '>' + selectData[i].Name + '</option>';
   }

   return html;
}

每個人都忘記了解決這些問題的“經典”方法:使用foreach循環並實際編寫輸入 html。唯一的缺點是您必須添加自動屬性的東西(如驗證等),這取決於您的目的可能沒什麼大不了的。

就像是:

<select> // add other attributes as expected
@foreach(var type in Model.MyFancyTypes) {
<option value="@type.SubTypeID" data-description="@type.Description" 
   @if(ViewBag.TypeSelected == type.SubTypeID) {
       selected="selected"
   }>@type.Name</option>
}
</select>

引用自:https://stackoverflow.com/questions/11285303