2014-01-14 4 views
0

Я создаю приложение MVC4 с использованием механизма Razor View, и я хотел бы принять решение в моем View на основе количества элементов в Select List. Мои списки выбора создаются в контроллере и сохраняются в коллекции ViewData. В принципе, если в списке выбора есть только один элемент, я планирую скрыть раскрывающееся меню в представлении и скорректировать его значение с помощью скрытого поля.MVC4 Просмотр решения по количеству элементов в списке выбора

Когда я обращаюсь к свойству «Items», Intellisense не предоставляет метод подсчета количества элементов списка. Как подсчитать элементы в списке выбора из представления Razor?

Index.cshtml

@model Mvc4.Models.PhoneRecord 
... 
    <div class="editor-field"> 
     @{ 
      // I need logic here to count items in the select list. 
      // XXXXX is of course a compile error, there is no Intellisense 
      // option that provides a "count" method, what should I use? 
      if (((SelectList)ViewData["_CellPhoneCarrier"]).Items.XXXXX == 1)) 
      { 
       @Html.Raw("note: value is hardcoded.") 
       @Html.HiddenFor(m => m.CellPhoneCarrier) 
      } 
      else 
      { 
       @Html.DropDownListFor(m => m.CellPhoneCarrier, (SelectList)ViewData["_CellPhoneCarrier"]) 
      } 
     } 
    </div> 
... 
+3

Почему бы не помещать информацию в строго типизированную модель - было бы намного проще в использовании? .. –

+0

Вы * должны * иметь возможность использовать Count() (расширение linq), я считаю, intellisense или нет.С другой стороны, предложение Алексея еще лучше! –

+0

Alexei, я использовал ViewData, потому что именно так показал учебник - мне это не нравится tbh. – laylarenee

ответ

2

Чтобы ответить на ваш вопрос прямо, вам просто нужно сделать использование метода Count(), например, так:

if (((SelectList)ViewData["_CellPhoneCarrier"]).Items.Count() == 1)) 

Однако я согласен с Алексеем. Создание представлений намного проще, если вы используете сильно типизированные модели. Вы могли бы что-то вроде этого:

public class CellPhoneCarriersViewModel 
{ 
    public SelectList Items { get; set; } 
    public int CellPhoneCarrier { get; set; } 
} 

Теперь, вместо того, чтобы хранить ваши SelectList внутри ViewData, вы можете создать его в контроллере и не имеют прямого доступа к нему:

public ActionResult Index() 
{ 
    var model = new CellPhoneCarriersViewModel(); 
    model.Items = new SelectList(...); 

    return View(model); 
} 

Там больше нет необходимости чтобы запутать вещи в представлении. Таким образом, вид становится:

@if (Model.Items.Count() == 1) 
{ 
    @Html.HiddenFor(m => m.CellPhoneCarrier) 
} 
else 
{ 
    @Html.DropDownListFor(m => m.CellPhoneCarrier, Model.Items) 
} 

Если вы собираетесь использовать это в нескольких местах, вы можете очистить свои взгляды еще далее, написав метод расширения, чтобы сделать это для вас:

public static class HtmlExtensions 
{ 
    public static HtmlString HiddenOrDropDownFor<TModel, TProperty>(this HtmlHelper<TModel> helper, 
     Expression<Func<TModel, TProperty>> target, IEnumerable<SelectListItem> selectList) 
    { 
     if (selectList.Count() == 1) 
      return helper.HiddenFor(target); 

     return helper.DropDownListFor(target, selectList); 
    } 
} 

Затем используйте его в своем виде так:

@Html.HiddenOrDropDownFor(m => m.CellPhoneCarrier, Model.Items) 
+0

Я попытался 'Items.Count()' во-первых, он выдает ошибку компиляции для меня: 'System.Collections.IEnumerable не содержит определения для Count ...' – laylarenee

+0

@LaylaRenee Метод '.Count()' является Метод расширения LINQ. Вам нужно добавить оператор 'using System.Linq;'. –

+1

Это сработало отлично. Я добавил свойство Select List в свой ViewModel и использовал его, как описано здесь. Использование строго типизированного подхода намного превосходит то, что я использовал, спасибо большое. Я также очень ценю этот «бонусный ответ» относительно HtmlExtensions! – laylarenee

0

Создание ICollection из CellPhoneCarriers в ViewModel затем использовать эту ViewModel в этом представлении.

ака:

public class PhoneRecordVM 
{ 
    public ICollection<CellPhoneCarrier> CellPhoneCarriers { get; set; } 

    public PhoneRecordVM(Customer customer) 
    { 
     CellPhoneCarriers = (db.CellPhoneCarrier) 
      .Where(e => e.CarrierZone == customer.Zone) 
      .OrderBy(e => e.CellPhoneCarrier.Text)) 
      .ToList(); 
    } 
} 

В Вид:

if(SelectList(Model.CellPhoneCarriers, "ID", "CellPhoneCarrier.Text", Model.SelectedCellPhoneCarrierID).Count ==1) 
{...} 
else 
{...} 
1

Вы должны поместить SelectionList в модель. Затем в View вы могли бы сделать что-то вроде этого:

 @{ 
     int nbrOfCarrier = Model.CellPhoneCarrierList().Count(); 

     if (nbrOfCarrier > 1) 
     { 
      @Html.DropDownListFor(m => m.CellPhoneCarrier,Model.CellPhoneCarrierList()) 
     } 
     else 
     { 
      @Html.HiddenFor(m => m.CellPhoneCarrier, "1") 
     } 

    } 

и в модели,

public List<SelectListItem> CellPhoneCarrierList() 
    { 
     List<SelectListItem> x = new List<SelectListItem>(); 
     x.Add(new SelectListItem { Text = "AT&T", Value = "1" }); 
     x.Add(new SelectListItem { Text = "T-Mobile", Value = "2"}); 
     x.Add(new SelectListItem { Text = "Verizon", Value = "3" }); 
     return x; 
    } 

использование Entity Framework и хранимые процедуры для заполнения Select List. Даже добавьте другие уровни для DAL и BLL для масштабируемости. Я бы никогда не поместил код в контроллер, кроме того, если операторы и решения обрабатывать разными способами в Модели на основе ввода пользователем

+0

Я использую слой репозитория для заполнения элементов в списке выбора. Как включить репозиторий в этот метод? Кажется, мне придется либо жестко закодировать репозиторий в Модели, либо передать интерфейс в метод из представления? – laylarenee

+0

Я попытался проверить это сегодня, перегрузка, которую вы предоставили, приводит к ошибке компиляции. – laylarenee

+0

Вы не забыли добавить с помощью System.Web.Mvc в модель? SelectListItem находится в System.Web.Mvc. Я тестировал этот код перед публикацией. Если вы используете дополнительный слой, создайте класс и метод, который читает из EF, и либо возвратите общую коллекцию, либо сделайте foreach в этом методе и заполните List и верните его. Есть много способов кожи кошки. Просто убедитесь, что используете Web.Mvc – Yogi

Смежные вопросы