Выберите помощник по тегам в 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="???" />
Я был бы признателен за помощь в этом. Спасибо.
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