Выберите помощник по тегам в ASP.NET ядро MVC



мне нужна помощь с помощью Select tag helper in ASP.NET ядро.



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



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


мой класс employee выглядит так:



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


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



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


Я был бы признателен за помощь в этом. Спасибо.

718   5  

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 asp-for="EmployeeId" asp-items="@Model.Employees" />

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

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

получение данных из таблицы базы данных с помощью Entity framework

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

предположим, что ваш объект 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 это ваш объект контекста БД. Код представления такой же, как выше.

С Помощью 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 метод получения списка объектов сотрудников, каждый с помощью Id и FirstName свойство и я использую эти свойства как DataValueField и DataTextField на SelectList объект, который мы создали. Вы можете изменить жестко закодированный список на код, который считывает данные из таблицы базы данных.

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

<select asp-for="EmployeeId" asp-items="@Model.Employees" >
    <option>Please select one</option>
</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 при отображении страницы.

Multi select dropdown

если вы хотите отобразить выпадающее меню multi 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 and 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);
}

нет никаких изменений в код вида. помощник по выбору тегов теперь будет отображать параметры внутри 2 optgroup предметы.

Я создал интерфейс и <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; }
}

The <options> tag helper:

[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>");
            }
        }
    }
}

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

вы также можете использовать 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;

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

<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>

В Get : // ПОЛУЧИТЬ: общественные IActionResult создать() {

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

        return View();
    }

В Должности : var selectedIds= запрос.Форма ["Теги"];

В Виде :

                            <label>Tags</label>
                            <select  asp-for="Tags"  id="Tags" name="Tags" class="form-control" asp-items="ViewBag.Tags" multiple></select>

Comments

    Ничего не найдено.