2012-01-05 67 views
0

我想在我的視圖中實現編輯地址。MVC中的下拉框3

地址具有街道,城鎮等的基本字符串。它還具有國家ID。我在我的國家數據庫中有一個表格。

在我控制我創建的SelectList這些國家:

ViewBag.Countries = _countryRepo.GetAll().Select(c => new SelectListItem { Text = c.Name, Value = c.Id }); 

現在,在我看來,我希望能夠利用這個選擇列表允許用戶選擇國家。

我本來以爲:

@Html.DropDownList("countryId", (IEnumerable<Country>)ViewBag.Countries, "Select") 

我有兩個地址:

public class Company() 
{ 
    public Address HeadOffice { get; set; } 
    public Address SecondOffice { get; set; } 
} 

所以顯示視圖時,我需要有所示的選擇國家。我不認爲我可以做到這一點在我的控制器,因爲如果我選擇一個這樣的:

ViewBag.Countries = _countryRepo.GetAll().Select(c => new SelectListItem { Text = c.Name, Value = c.Id, Selected = c.Id == model.HeadOffice.Id ? true : false }); 

這隻會爲HeadOffice上工作。

從我可以有兩種選擇。有兩個不同的選擇列表或在視圖中手動構建選擇列表:

<select name="HeadOffice.CountryId"> 
    @foreach(var c in (IEnumerable<Country>)ViewBag.Countries) 
    { 
     <option value="@c.Id" @(c.Id == Model.HeadOffice.Id ? "selected='true'" : "">@c.Name</option> 
    } 
</select> 

什麼是最佳方式?這兩個看起來不對,也不好。有沒有更好的方法來解決這個問題?

回答

2

我會用一個視圖模型,它接受國家名單一次,然後露出2名不同的列表。這樣,你只查詢數據庫的人,但仍讓你查看乾淨

視圖模型:

public class MyViewModel 
{ 
    public Address HeadOffice { get; set; } 
    public Address SecondOffice { get; set; } 

    public IEnumerable<Country> Countries { get;set;} 

    public IEnumerable<SelectListItem> HeadOfficeCountries 
    { 
    get 
    { 
     return GetCountriesList(Countries, HeadOffice.Id); 
    } 
    } 

    public IEnumerable<SelectListItem> SecondOfficeCountries 
    { 
    get 
    { 
     return GetCountriesList(Countries, SecondOffice.Id); 
    } 
    } 

    private IEnumerable<SelectListItem> GetCountriesList(IEnumerable<Country> countries, int forAddress) 
    { 
    return countries.Select(c => new SelectListItem { Text = c.Name, Value = c.Id, Selected = c.Id == forAddress ? true : false }); 
    } 
} 
+0

優秀!好主意 - 我會這樣做的。謝謝。 – Terry 2012-01-05 20:40:05

+0

@特里偉大!很高興我能幫上忙。 – 2012-01-05 20:43:34

+0

@BassamMehanni你在這裏寫了兩次相同的代碼。 ASP.NET MVC的原則之一是遵循DRY方法。 – tugberk 2012-01-05 20:46:56

1

看一看下面的博客文章:

A Way of Working with Html Select Element (AKA DropDownList) In ASP.NET MVC

你會發現博客文章內的所有細節。

編輯:

對於你的情況,下面的代碼應該很好地工作:

public ActionResult Index() { 

    ViewBag.DLForHeadOffice = GetItems(model.HeadOffice.Id); 
    ViewBag.DLForSecondOffice = GetItems(model.SecondOffice.Id); 

    //continue your code 
} 


private IEnumerable<SelectListItem> GetItems(int id) { 

    _countryRepo.GetAll(). 
     Select(c => 
      new SelectListItem { 
       Text = c.Name, 
       Value = c.Id, 
       Selected = c.Id == id ? true : false 
      } 
     );  
} 
+0

博客帖子鏈接已丟失,但我不認爲這是有意的。 – 2012-01-05 20:34:03

+0

@FrazellThomas現在它在那裏。 – tugberk 2012-01-05 20:34:47

+0

謝謝,但我已經知道如何使用下拉列表。我的問題是讓它適用於兩個不同地址的最佳方式。 – Terry 2012-01-05 20:39:42

0

你有沒有考慮使用HTML助手?

我在我們的類中有一些處理字典緩存的私有靜態字典變量,所以我們不必在每次渲染下拉列表時獲取國家列表(這就是countryDictionary的下面)。

public static MvcHtmlString CountrySelectFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string emptyText, object htmlAttributes) 
    { 
     SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = emptyText != null ? emptyText : "", Value = "" } }; 
     return htmlHelper.DropDownListFor(expression, emptyText != null ? SingleEmptyItem.Concat(new SelectList(countryDictionary, "Key", "Value")) : new SelectList(countryDictionary, "Key", "Value"), htmlAttributes); 
    } 

從這裏,你註冊,你把你的HTML助手在命名空間後,您可以使用:

<%: Html.CountrySelectFor(model => Model.HeadOffice.CountryId) %> 

僅供參考,這裏是出於對countryList片段。下面的「Caching」行不會爲您存在,這些是我們爲管理應用程序緩存而創建的一些自定義類。

private static Dictionary<int, string> countryList 
    { 
     get 
     { 
      IList<Models.Country> countries = Caching.HTTPCache.Get(Caching.Common.CountryCacheName) as IList<Models.Country>; 

      if (countries == null) 
      { 
       countries = Models.Country.Get(); //Loads all countries from the DB 
       Caching.HTTPCache.Add(Caching.Common.CountryCacheName, countries , new TimeSpan(0, 0, Caching.Common.CountryCacheDuration, 0, 0)); //Adds the results to the cache 
      } 

      return countries .ToDictionary(t => t.CountryId, t => t.CountryName); 
     } 
    }