Выпадающие окна в MVC 3 - PullRequest
       18

Выпадающие окна в MVC 3

0 голосов
/ 06 января 2012

Я пытаюсь реализовать редактирование адресов в моем представлении.

Адрес имеет основные строки для улицы, города и т. Д. Он также имеет идентификатор страны.У меня есть таблица в моей базе данных стран.

В моем контроллере я создаю список выбора для этих стран:

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>

Каков наилучший способ?Оба кажутся неправильными и не хорошими.Есть ли лучший способ решить эту проблему?

Ответы [ 3 ]

2 голосов
/ 06 января 2012

Я бы использовал ViewModel, который получает список стран один раз, а затем выставляет 2 разных списка. Таким образом, вы запрашиваете только те базы данных, но сохраняете чистоту. View *

ViewModel:

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 });
  }
}
1 голос
/ 06 января 2012

Посмотрите на следующее сообщение в блоге:

Способ работы с HTML-элементом выбора (AKA DropDownList) в ASP.NET MVC

Все подробности вы найдете в записи блога.

Edit:

Для вашего случая приведенный ниже код должен работать нормально:

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 голосов
/ 06 января 2012

Рассматривали ли вы использование 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 Helper, вы можете использовать:

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

Только для справкиВот фрагмент кода для countryList.Строки «Кэширование» ниже для вас не будут существовать, это некоторые пользовательские классы, которые мы создали для управления кешем приложений.

 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);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...