Мы можем использовать $ .extend (true, object1, object2) для глубокого слияния. Значение true обозначает объединение двух объектов рекурсивно, изменение первого.
Использование помощников 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>
Подобно одиночному 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 .
Вы также можете использовать 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;
В 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>
Для этого я создал интерфейс и помощник тега <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>");
}
}
}
}
Возможно, опечатка, но цель ясна, я думаю. Мне пришлось немного отредактировать.
вы можете использовать код ниже для множественного выбора:
<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>
List<SelectListItem>
как свойство в своей модели просмотра, вам не нужно его преобразовывать в представление. См. Мое обновление в ответе. – Shyju 6 January 2016 в 02:54List<SelectListItem>
должен находиться в соответствующем классе модели (класс Employee в этом сообщении)? – nam 5 July 2016 в 17:40<option>Please select one</option>
– Serj Sagan 5 August 2016 в 01:50