Как написать Html.DropDownListFor () для перечислимого в модели? [Дубликат]

Мы можем использовать $ .extend (true, object1, object2) для глубокого слияния. Значение true обозначает объединение двух объектов рекурсивно, изменение первого.

$ extend (true, target, object)

87
задан Shyju 30 September 2016 в 01:34
поделиться

5 ответов

Использование помощников Select Tag для отображения элемента SELECT в вашем представлении

В вашем действии 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; }
}

И в вашем действии 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.

Убедитесь, что вы используете явный закрывающий тег для элемента select. Если вы используете подход с закрывающим тегом, помощник тега будет отображать пустой элемент SELECT!

Подход ниже не будет работать

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

Но это будет работать.

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

Получение данных из вашей таблицы базы данных с использованием сущности framework

В приведенных выше примерах используются жестко закодированные элементы для параметров. Поэтому я подумал, что добавлю некоторый пример кода для получения данных с использованием инфраструктуры 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, который мы создали. Вы можете изменить список жестких дисков на код, который считывает данные из таблицы базы данных.

Код представления будет таким же.

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

Извлечь элемент SELECT из списка строк .

Иногда вам может понадобиться отобразить элемент 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 для элемента select с атрибутом 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>

Настройка выбранные опции в multi select

Подобно одиночному 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 и Джерри в элементе multi select при рендеринге страницы.

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

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

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

и в view

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

Группировка элементов

Метод вспомогательного тега 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 tag теперь отобразит параметры внутри 2 элементов optgroup .

188
ответ дан Shyju 19 August 2018 в 18:05
поделиться
  • 1
    Спасибо! Это похоже на старый синтаксис бритвы, где нам нужно выполнить преобразование в SelectList. Еще раз спасибо. – Sam 6 January 2016 в 02:46
  • 2
    Добро пожаловать! Если вы используете List<SelectListItem> как свойство в своей модели просмотра, вам не нужно его преобразовывать в представление. См. Мое обновление в ответе. – Shyju 6 January 2016 в 02:54
  • 3
    @Shyju Этот тип свойства List<SelectListItem> должен находиться в соответствующем классе модели (класс Employee в этом сообщении)? – nam 5 July 2016 в 17:40
  • 4
    Нет. В модели просмотра мы используем модель представления для создания элемента select. Мы не используем класс сущности в представлении. – Shyju 5 July 2016 в 17:41
  • 5
    Я искал, как добавить пустую опцию, спасибо за использование <option>Please select one</option> – Serj Sagan 5 August 2016 в 01:50
  • 6

Вы также можете использовать 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;
3
ответ дан Amir Rezaei 19 August 2018 в 18:05
поделиться

В Get: // GET: public IActionResult Create () {

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

        return View();
    }

In Post: var selectedIds = Request.Form ["Теги"];

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

                            <label>Tags</label>
                            <select  asp-for="Tags"  id="Tags" name="Tags" class="form-control" asp-items="ViewBag.Tags" multiple></select>
0
ответ дан Anas Al-Qudah 19 August 2018 в 18:05
поделиться

Для этого я создал интерфейс и помощник тега <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>");
            }
        }
    }
}

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

9
ответ дан Yves 19 August 2018 в 18:05
поделиться

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

<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>
1
ответ дан Zubayer Bin Ayub 19 August 2018 в 18:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: