我正在尝试创建一个页面,其中包含3个级联下拉列表,用于车辆制造,模型和变体。
单击“搜索”按钮必须将页面发布到另一个控制器并使用ViewModel进行查看,ViewModel将显示在索引页面上选择的车辆的详细信息。
楷模
public class Vehicle
{
public IEnumerable<SelectListItem> Make{ get; set; }
public IEnumerable<SelectListItem> Model { get; set; }
public IEnumerable<SelectListItem> Variant { get; set; }
}
public class Details
{
public string PowerOutput{ get; set; }
public string NumberOfDoors{ get; set; }
public string VariantName { get; set; }
}
HomeController的
VehicleEntities db = new VehicleEntities();
public ActionResult Index()
{
var model = new Vehicle
{
BrandName = GetMakes()
};
return View(model);
}
private IEnumerable<SelectListItem> GetMakes()
{
IEnumerable<SelectListItem> brandname = from s in db.prcGetMakes(null)
select new SelectListItem
{
Selected = s.Make.ToString() == "Active",
Text = s.Make,
Value = s.Make
};
return new SelectList(brandname, "Value", "Text");
}
public JsonResult GetModels(string make)
{
var list = db.prcGetModels(make);
return Json(new SelectList(list, "Model", "Model"), JsonRequestBehavior.AllowGet);
}
public JsonResult GetVariants(string model)
{
var list = db.prcGetVariants(model);
return Json(new SelectList(list, "Variant", "Variant"), JsonRequestBehavior.AllowGet);
}
视图
@model WebApplication7.ViewModels.VehicleDetailsViewModel**
@using (Html.BeginForm("Index", "Vehicle", FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<div class="form-group">
<div class="col-md-3">
@Html.Label("Make", new { @class = "col-md-2 control-label" })
@Html.DropDownList("Make", Model.Make as SelectList, htmlAttributes: new { @class = "form-control minimal", @onchange = "refreshModelFromBrandName()" })
</div>
<div class="col-md-3">
@Html.LabelFor(model => model.Model, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.DropDownList("Model", Model.Model as SelectList, htmlAttributes: new { @class = "form-control minimal", @onchange = "refreshVariantFromModel()" })*@
</div>
<div class="col-md-3">
@Html.LabelFor(model => model.Brand, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.DropDownList("Variant", Model.Variant as SelectList, htmlAttributes: new { @class = "form-control minimal", @onchange = "" })*@
</div>
<div class="col-md-3">
<input id="search" type="submit" value="Search" />
</div>
</div>
}
<script type="text/javascript">
function refreshBrandName() {
// get references to the source and target drop downs html controls
// These are jquery searches to find the drop down controls
// find a control with id=BrandName
src = $("#Make");
// find a control with id=Model (you need to add this to your view)
tgt = $("#BrandName");
// clear drop down
tgt.empty();
// Get new model dataset via ajax
// based on BrandName
// The url parameter points at your web method
$.ajax({
type: 'GET',
//url: 'GetMakes',
url: 'GetMakes',
dataType: 'json',
data: { brandName: src.val() },
// success is called when dataset returns
success: function (p) {
// Populate with each returned member
$.each(p, function (i, pr) {
tgt.append(
'<option value="' + pr.Value + '">' +
pr.Text + '</option>'
);
})
}
});
}
function refreshModelFromBrandName() {
// get references to the source and target drop downs html controls
// These are jquery searches to find the drop down controls
// find a control with id=BrandName
src = $("#Make");
// find a control with id=Model (you need to add this to your view)
tgt = $("#Model");
// clear drop down
tgt.empty();
// Get new model dataset via ajax
// based on BrandName
// The url parameter points at your web method
$.ajax({
type: 'GET',
url: 'GetModels',
dataType: 'json',
data: { brandName: src.val() },
// success is called when dataset returns
success: function (p) {
// Populate with each returned member
$.each(p, function (i, pr) {
tgt.append(
'<option value="' + pr.Value + '">' +
pr.Text + '</option>'
);
})
}
});
}
function refreshVariantFromModel() {
// get references to the source and target drop downs html controls
// These are jquery searches to find the drop down controls
// find a control with id=BrandName
src = $("#Model");
// find a control with id=Model (you need to add this to your view)
tgt = $("#Variant");
// clear drop down
tgt.empty();
// Get new model dataset via ajax
// based on BrandName
// The url parameter points at your web method
$.ajax({
type: 'GET',
url: 'GetVariants',
dataType: 'json',
data: { modelName: src.val() },
// success is called when dataset returns
success: function (p) {
// Populate with each returned member
$.each(p, function (i, pr) {
tgt.append(
'<option value="' + pr.Value + '">' +
pr.Text + '</option>'
);
})
}
});
}
</script>
这很好地工作,级联下拉菜单按预期执行,表单发布到正确的控制器
VehicleController
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(Details model)
{
return View(model);
}
但这是我被卡住的地方。如何让Vehicle Controller将VehicleDetail ViewModel传递给连接到Vehicle Controller的View?
我知道它与我在HomeController中仅使用Vehicle类的事实有关,但我不知道如何创建VehicleDetailsViewController的实现,以便ViewModel在HomeController视图和VehicleController视图上工作。
我认为ViewModel必须是这样的
public class VehicleDetailsViewModel
{
public IEnumerable<SelectListItem> Brands { get; set; }
public IEnumerable<SelectListItem> Models { get; set; }
public IEnumerable<SelectListItem> Variants { get; set; }
public string PowerOutput { get; set; }
public string NumberOfDoors { get; set; }
public string VariantName { get; set; }
public VehicleDetailsViewModel()
{
this.Brands = new List<SelectListItem>();
this.Models = new List<SelectListItem>();
this.Variants = new List<SelectListItem>();
}
}
任何帮助都感激不尽 :)
通常我会做下一个:
public ActionResult Index()
{
var vm = new VehicleDetailsViewController();
return View(vm);
}
[HttpPost]
public ActionResult Index(VehicleDetailsViewController vm)
{
//Validation something wrong
if (!ModelState.IsValid) return View(vm);
//Make what you want with all OK
return View("AllOk");
}