Заполнение и выбор значения раскрывающегося списка в ASP.NET MVC 4
Выпадающие списки в ASP.NET MVC смущают меня. У меня есть модельный класс. В классе модели есть строка SelectedValue. Эта строка представляет это ранее выбранное значение. У меня есть коллекция предметов, которые я вытащил из базы данных. Каждый элемент коллекции имеет идентификатор и значение имени. Моя проблема в том, что я не знаю, каков рекомендуемый способ получения этой информации в пользовательском интерфейсе.
Я не уверен, должен ли я использовать ViewBag или Модель. Как только значение будет там, я даже не уверен, каков наилучший способ заполнить пользовательский интерфейс. Я видел помощников HTML и людей, использующих синтаксис RAZOR. Я очень смущен. Что люди рекомендуют?
Спасибо
4 ответа
Вот как я это делаю, скажем, у вас есть 2 модели Team and Player
:
Player.cs
public class Player
{
[HiddenInput(DisplayValue = false)]
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[ForeignKey("Team")]
[Display(Name = "Team")]
public int TeamId { get; set; }
[Display(Name = "First name")]
public string FirstName { get; set; }
[Display(Name = "Last name")]
public string LastName { get; set; }
public virtual Team Team { get; set; }
}
Team.cs
public class Team
{
[Key]
[HiddenInput(DisplayValue = false)]
public int TeamId { get; set; }
[Display(Name = "Full Name:")]
public string Name { get; set; }
public virtual ICollection<Player> Players { get; set; }
}
Затем в вашем PlayerController:Примечание: команда должна существовать, чтобы создать игрока
private void PopulateTeamsDropDownList(object selectedTeams = null)
{
var teamsQuery = from d in _dataSource.Teams
orderby d.Name
select d;
ViewBag.TeamID = new SelectList(teamsQuery, "TeamId", "Name", selectedTeams);
}
[HttpGet]
public ActionResult Create()
{
PopulateTeamsDropDownList();
return View();
}
[HttpPost]
public ActionResult Create(Player model)
{
if (ModelState.IsValid)
{
using (EFootballDb db = new EFootballDb())
{
try
{
var player = new Player
{
FirstName = model.FirstName,
LastName = model.LastName
};
db.Players.Add(player);
db.SaveChanges();
return RedirectToAction("About", "Home");
}
catch (Exception)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}
}
PopulateTeamsDropDownList(model.TeamId);
return View(model);
}
И, наконец, ваш Create View for Player будет выглядеть так:
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Player</legend>
<div class="editor-label">
@Html.LabelFor(model => model.TeamId, "Pick Your Team")
</div>
<div class="editor-field">
@Html.DropDownList("TeamId", String.Empty)
@Html.ValidationMessageFor(model => model.TeamId)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.FirstName)
@Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.LastName)
@Html.ValidationMessageFor(model => model.LastName)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
То, как я это делаю, делает раскрывающийся список частью моей ViewModel.... скажем, это продукты.... так что в моей ViewModel у меня есть
public SelectList Products { get; set;}
public int ProductId { get; set; } // For the the selected Product
Поэтому, когда представление загружается, и я заполняю модель, чтобы вернуться к представлению в контроллере, я делаю что-то вроде этого:
model.Products = new SelectList(MyEnumerableofProducts, "ValueField", "TextField", {value of the selected item in the dropdown, as a string)
На мой взгляд, я бы имел:
@Html.DropDownListFor(model => model.ProductId, Model.Products, "Please Select")
return View(model)
В дополнение к описанным выше методам, вы также можете использовать этот подход для использования нескольких внешних ключей в таблице поиска. Это очень ясно и эффективно, насколько я видел.
Если вы используете VB.Net - MVC4- Razor Этот ответ почти такой же, как Frigik(спасибо Frigik)
В вашей модели создайте два поля: одно - это поле, в котором будет храниться SelectedItem(здесь это TagType of string), а второе - раскрывающиеся значения (TagTypeList).
Модельный класс- Tag.vb
Imports System.Web.Mvc
Private _tagType As String
Private _tagTypeList As List(Of SelectListItem)
Public Property TagType() As String
Get
Return _tagType
End Get
Set(ByVal value As String)
_tagType = value
End Set
End Property
Public Property TagTypeList() As List(Of SelectListItem)
Get
Return _tagTypeList
End Get
Set(value As List(Of SelectListItem))
_tagTypeList = value
End Set
End Property
'In the constructor
Sub New()
TagTypeList = CommonUtility.LoadDropDownByName("TAGTYPE")
End Sub
В классе CommonUtility - CommonUtility.vb
Imports System.Web.Mvc
Imports System.Collections.Generic
Public Shared Function LoadDropDownByName(ByVal DropDownName As String) As List(Of SelectListItem)
Dim dt As DataTable
Dim ds As DataSet
Dim results As List(Of SelectListItem) = Nothing
Try
ds = objSignOn.LoadDropDown(DropDownName) 'Pass the dropdown name here and get the values from DB table which is - select ddlId, ddlDesc from <table name>
If Not ds Is Nothing Then
dt = ds.Tables(0)
If (dt.Rows.Count > 0) Then
results = (From p In dt Select New SelectListItem With {.Text = p.Item("ddlDesc").ToString(), .Value = p.Item("ddlId").ToString()}).ToList()
End If
End If
Catch ex As Exception
End Try
Return results
End Function
В представлении
@Html.DropDownListFor(Function(x) x.TagType, Model.TagTypeList, "", New With {.id = "ddlTagType",.class = "dropDown", .style = "width: 140px"})
Здесь 3-й параметр (необязательно) как пустой, который будет вставлять 1-й элемент как пустой в раскрывающемся списке. Первым параметром является selectedItem, который помогает заполнить, когда значение уже присутствует в таблице БД.
Надеюсь, это поможет тем, кто использует VB.Net