2016-01-06 2 views
63

Мне нужна помощь с помощником select tag в ASP.NET Core.Выберите помощник тега в ASP.NET Core MVC

У меня есть список сотрудников, которых я пытаюсь связать с помощником select tag. Мои сотрудники находятся в List<Employee> EmployeesList, и выбранное значение перейдет в EmployeeId. На мой взгляд модель выглядит следующим образом:

public class MyViewModel 
{ 
    public int EmployeeId { get; set; } 
    public string Comments { get; set; } 
    public List<Employee> EmployeesList {get; set; } 
} 

Мой класс работник выглядит следующим образом:

public class Employee 
{ 
    public int Id { get; set; } 
    public string FullName { get; set; } 
} 

Мой вопрос, как я могу сказать, мой выбора помощника тег использовать Id в качестве значения при отображении FullName в выпадающий список?

<select asp-for="EmployeeId" asp-items="???" /> 

Буду признателен за помощь в этом. Благодарю.

+1

просто что-то я думал, что я должен добавить, что, кажется, не будет работать, если вы закрыть выбери тег немедленно всегда закрыть тег с помощником тега не работает с <выбрать Asp- для ..... /> – RoughPlace

+0

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

ответ

130

Использование Select Tag хелперы для визуализации ВЫБЕРИТЕ элемент на ваш взгляд

В вашем GET действия, создать объект модели представления, загрузить коллекцию свойство EmployeeList и отправить его к просмотру.

public IActionResult Create() 
{ 
    var vm = new MyViewModel(); 
    vm.EmployeesList = new List<Employee> 
    { 
     new Employee {Id = 1, FullName = "Shyju"}, 
     new Employee {Id = 2, FullName = "Bryan"} 
    }; 
    return View(vm); 
} 

И в вашем создать взгляд, создать новый SelectList объект из EmployeeList имущества и передать в качестве значения для asp-items собственности.

@model MyViewModel 
<form asp-controller="Home" asp-action="Create"> 
    <select asp-for="EmployeeId" 
      asp-items="@(new SelectList(Model.EmployeesList,"Id","FullName"))"> 
     <option>Please select one</option> 
    </select> 
    <input type="submit"/> 
</form> 

И ваш метод действия HttpPost для принятия представленных данных формы.

[HttpPost] 
public IActionResult Create(MyViewModel model) 
{ 
    // check model.EmployeeId 
    // to do : Save and redirect 
} 

Или если ваша модель имеет вид List<SelectListItem> как свойство для ваших раскрывающихся пунктов.

public class MyViewModel 
{ 
    public int EmployeeId { get; set; } 
    public string Comments { get; set; } 
    public List<SelectListItem> Employees { set; get; } 
} 

И прибудете действия,

public IActionResult Create() 
{ 
    var vm = new MyViewModel(); 
    vm.Employees = new List<SelectListItem> 
    { 
     new SelectListItem {Text = "Shyju", Value = "1"}, 
     new SelectListItem {Text = "Sean", Value = "2"} 
    }; 
    return View(vm); 
} 

И в представлении, вы можете напрямую использовать Employees свойство для asp-items.

@model MyViewModel 
<form asp-controller="Home" asp-action="Create"> 
    <label>Comments</label> 
    <input type="text" asp-for="Comments"/> 

    <label>Lucky Employee</label> 
    <select asp-for="EmployeeId" asp-items="@Model.Employees" > 
     <option>Please select one</option> 
    </select> 
    <input type="submit"/> 
</form> 

Класс SelectListItem принадлежит Microsoft.AspNet.Mvc.Rendering имен.

Получение данных из таблицы базы данных с использованием фреймворка Entity

Приведенные выше примеры используют жестко закодированные элементы для опций. Поэтому я подумал, что добавлю примерный код для получения данных с использованием инфраструктуры Entity, как это многие люди используют.

Давайте предположим, что ваш объект DbContext имеет свойство Employees, которое типа DbSet<Employee> где класс Employee предприятия имеет Id и Name свойство, как этого

public class Employee 
{ 
    public int Id { set; get; } 
    public string Name { set; get; } 
} 

Вы можете использовать запрос Linq, чтобы получить сотрудник и используйте метод Select в выражении linq для создания списка объектов SelectListItem для каждого сотрудника.

public IActionResult Create() 
{ 
    var vm = new MyViewModel(); 
    vm.Employees = context.Employees 
          .Select(a => new SelectListItem() { 
           Value = a.Id.ToString(), 
           Text = a.Name 
          }) 
          .ToList(); 
    return View(vm); 
} 

Предполагая, что context - ваш объект контекста db. Код вида такой же, как и выше.

Использование SelectList

Некоторые люди предпочитают использовать SelectList класс для хранения элементов, необходимых для визуализации параметров.

public class MyViewModel 
{ 
    public int EmployeeId { get; set; } 
    public SelectList Employees { set; get; } 
} 

Теперь в вашем GET действия, вы можете использовать SelectList конструктор для заполнения Employees свойства модели представления. Убедитесь, что вы задаете параметры dataValueField и dataTextField.

public IActionResult Create() 
{ 
    var vm = new MyViewModel(); 
    vm.Employees = new SelectList(GetEmployees(),"Id","FirstName"); 
    return View(vm); 
} 
public IEnumerable<Employee> GetEmployees() 
{ 
    return new List<Employee> 
    { 
     new Employee { Id=1, FirstName="Shyju"}, 
     new Employee { Id=2, FirstName="Bryan"} 
    }; 
} 

Здесь я вызываю метод GetEmployees, чтобы получить список объектов Employee, каждый с имуществом Id и FirstName и я использую эти свойства, как DataValueField и DataTextField из SelectList объекта, который мы создали. Вы можете изменить hardcoded list на код, который считывает данные из таблицы базы данных.

Код вида будет таким же.

<select asp-for="EmployeeId" asp-items="@Model.Employees" > 
    <option>Please select one</option> 
</select> 

визуализации ВЫБЕРИТЕ элемент из списка строк.

Иногда вам может понадобиться отобразить элемент выбора из списка строк. В этом случае, вы можете использовать SelectList конструктор, который принимает только IEnumerable<T>

var vm = new MyViewModel(); 
var items = new List<string> {"Monday", "Tuesday", "Wednesday"}; 
vm.Employees = new SelectList(items); 
return View(vm); 

просмотра кода будет таким же.

Установка выбранных опций

Несколько раз, вы можете установить один из вариантов в качестве опции по умолчанию в SELECT, элемент (например, в окне редактирования, вы хотите загрузить ранее сохраненное значение параметра). Для этого вы можете просто установить значение свойства EmployeeId в значение параметра, который вы хотите выбрать.

public IActionResult Create() 
{ 
    var vm = new MyViewModel(); 
    vm.Employees = new List<SelectListItem> 
    { 
     new SelectListItem {Text = "Shyju", Value = "11"}, 
     new SelectListItem {Text = "Tom", Value = "12"}, 
     new SelectListItem {Text = "Jerry", Value = "13"} 
    }; 
    vm.EmployeeId = 12; // Here you set the value 
    return View(vm); 
} 

Это выберет вариант Tom в элементе select при визуализации страницы.

Мульти выберите выпадающий

Если вы хотите сделать мульти выберите выпадающий список, вы можете просто изменить вид модели свойство, которое вы используете для asp-for атрибута на ваш взгляд на тип массива.

public class MyViewModel 
{ 
    public int[] EmployeeIds { get; set; } 
    public List<SelectListItem> Employees { set; get; } 
} 

Это будет оказывать HTML-разметку для выбора элемента с атрибутом multiple, который позволит пользователю выбрать несколько вариантов.

@model MyViewModel 
<select id="EmployeeIds" multiple="multiple" name="EmployeeIds"> 
    <option>Please select one</option> 
    <option value="1">Shyju</option> 
    <option value="2">Sean</option> 
</select> 

Настройка выбранного варианта в нескольких выберите

Аналогично выделим выбора, установите значение EmployeeIds свойства в массиве значений, которые вы хотите.

public IActionResult Create() 
{ 
    var vm = new MyViewModel(); 
    vm.Employees = new List<SelectListItem> 
    { 
     new SelectListItem {Text = "Shyju", Value = "11"}, 
     new SelectListItem {Text = "Tom", Value = "12"}, 
     new SelectListItem {Text = "Jerry", Value = "13"} 
    }; 
    vm.EmployeeIds= new int[] { 12,13} ; 
    return View(vm); 
} 

Это будет выбрать вариант Tom и Jerry в элементе multi select при визуализации страницы.

Использование ViewBag передать список элементов

Если вы не предпочитаете хранить свойства типа коллекции, чтобы передать список опций с точки зрения, вы можете использовать динамический ViewBag, чтобы сделать это. (Это не лично рекомендовали мой подход как viewbag динамично и ваш код подвержен ошибкам uncatched опечатки)

public IActionResult Create() 
{  
    ViewBag.Employees = new List<SelectListItem> 
    { 
     new SelectListItem {Text = "Shyju", Value = "1"}, 
     new SelectListItem {Text = "Sean", Value = "2"} 
    }; 
    return View(new MyViewModel()); 
} 

и в представлении

<select asp-for="EmployeeId" asp-items="@ViewBag.Employees"> 
    <option>Please select one</option> 
</select> 

Группировка предметов

Выбор: вспомогательный метод тег поддерживает группировки вариантов в раскрывающемся списке. Все, что вам нужно сделать, это указать значение свойства Group каждого элемента SelectListItem в вашем методе действий.

public IActionResult Create() 
{ 
    var vm = new MyViewModel(); 

    var group1 = new SelectListGroup { Name = "Dev Team" }; 
    var group2 = new SelectListGroup { Name = "QA Team" }; 

    var employeeList = new List<SelectListItem>() 
    { 
     new SelectListItem() { Value = "1", Text = "Shyju", Group = group1 }, 
     new SelectListItem() { Value = "2", Text = "Bryan", Group = group1 }, 
     new SelectListItem() { Value = "3", Text = "Kevin", Group = group2 }, 
     new SelectListItem() { Value = "4", Text = "Alex", Group = group2 } 
    }; 
    vm.Employees = employeeList; 
    return View(vm); 
} 

Код вида не изменяется. помощник тега select теперь отобразит параметры внутри 2 optgroup элементов.

+0

Спасибо! Это похоже на старый синтаксис бритвы, где нам нужно выполнить преобразование в SelectList. Еще раз спасибо. – Sam

+0

Добро пожаловать! Если вы используете 'List ' как свойство в вашей модели просмотра, вам не нужно преобразовывать его в представление. См. Мое обновление в ответе. – Shyju

+0

@Shyju Этот тип 'List ' должен находиться в соответствующем классе модели (класс Emoplyee в этом сообщении)? – nam

8

Для этого я создал интерфейс и вспомогательный тег <options>. Поэтому мне не пришлось конвертировать IEnumerable<T> в IEnumerable<SelectListItem> каждый раз, когда я должен заполнить элемент управления <select>.

И я думаю, что это прекрасно работает ...

Использование что-то вроде:

<select asp-for="EmployeeId"> 
    <option value="">Please select...</option> 
    <options asp-items="@Model.EmployeesList" /> 
</select> 

И заставить его работать с помощником тега вы должны реализовать этот интерфейс в своем классе:

public class Employee : IIntegerListItem 
{ 
    public int Id { get; set; } 
    public string FullName { get; set; } 

    public int Value { return Id; } 
    public string Text{ return FullName ; } 
} 

Эти необходимые коды:

Интерфейс:

public interface IIntegerListItem 
{ 
    int Value { get; } 
    string Text { get; } 
} 

<options> тега помощник:

[HtmlTargetElement("options", Attributes = "asp-items")] 
public class OptionsTagHelper : TagHelper 
{ 
    public OptionsTagHelper(IHtmlGenerator generator) 
    { 
     Generator = generator; 
    } 

    [HtmlAttributeNotBound] 
    public IHtmlGenerator Generator { get; set; } 

    [HtmlAttributeName("asp-items")] 
    public object Items { get; set; } 

    public override void Process(TagHelperContext context, TagHelperOutput output) 
    { 
     output.SuppressOutput(); 
     // Is this <options /> element a child of a <select/> element the SelectTagHelper targeted? 
     object formDataEntry; 
     context.Items.TryGetValue(typeof(SelectTagHelper), out formDataEntry); 

     var selectedValues = formDataEntry as ICollection<string>; 
     var encodedValues = new HashSet<string>(StringComparer.OrdinalIgnoreCase); 
     if (selectedValues != null && selectedValues.Count != 0) 
     { 
      foreach (var selectedValue in selectedValues) 
      { 
       encodedValues.Add(Generator.Encode(selectedValue)); 
      } 
     } 

     IEnumerable<SelectListItem> items = null; 
     if (Items != null) 
     { 
      if (Items is IEnumerable) 
      { 
       var enumerable = Items as IEnumerable; 
       if (Items is IEnumerable<SelectListItem>) 
        items = Items as IEnumerable<SelectListItem>; 
       else if (Items is IEnumerable<IIntegerListItem>) 
        items = ((IEnumerable<IIntegerListItem>)Items).Select(x => new SelectListItem() { Selected = false, Value = ((IIntegerListItem)x).Value.ToString(), Text = ((IIntegerListItem)x).Text }); 
       else 
        throw new InvalidOperationException(string.Format("The {2} was unable to provide metadata about '{1}' expression value '{3}' for <options>.", 
         "<options>", 
         "ForAttributeName", 
         nameof(IModelMetadataProvider), 
         "For.Name")); 
      } 
      else 
      { 
       throw new InvalidOperationException("Invalid items for <options>"); 
      } 

      foreach (var item in items) 
      { 
       bool selected = (selectedValues != null && selectedValues.Contains(item.Value)) || encodedValues.Contains(item.Value); 
       var selectedAttr = selected ? "selected='selected'" : ""; 

       if (item.Value != null) 
        output.Content.AppendHtml($"<option value='{item.Value}' {selectedAttr}>{item.Text}</option>"); 
       else 
        output.Content.AppendHtml($"<option>{item.Text}</option>"); 
      } 
     } 
    } 
} 

Там может быть некоторой опечатка, но цель ясна, я думаю. Мне пришлось немного отредактировать.

3

Вы также можете использовать IHtmlHelper.GetEnumSelectList.

// Summary: 
    //  Returns a select list for the given TEnum. 
    // 
    // Type parameters: 
    // TEnum: 
    //  Type to generate a select list for. 
    // 
    // Returns: 
    //  An System.Collections.Generic.IEnumerable`1 containing the select list for the 
    //  given TEnum. 
    // 
    // Exceptions: 
    // T:System.ArgumentException: 
    //  Thrown if TEnum is not an System.Enum or if it has a System.FlagsAttribute. 
    IEnumerable<SelectListItem> GetEnumSelectList<TEnum>() where TEnum : struct; 
1

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

<select asp-for="EmployeeId" multiple="multiple" asp-items="@ViewBag.Employees"> 
    <option>Please select</option> 
</select> 

вы также можете использовать:

<select id="EmployeeId" name="EmployeeId" multiple="multiple" asp-items="@ViewBag.Employees"> 
     <option>Please select</option> 
    </select> 
0

В Get: // GET: общественного IActionResult Создать() {

 ViewData["Tags"] = new SelectList(_context.Tags, "Id", "Name"); 

     return View(); 
    } 

In Post: var selectedIds = Request.Form ["Tags"];

В Виде:

      <label>Tags</label> 
          <select asp-for="Tags" id="Tags" name="Tags" class="form-control" asp-items="ViewBag.Tags" multiple></select> 
Смежные вопросы