使用 MVC Razor Entity Framework 和存储过程的级联下拉列表
Cascading dropdowns using MVC Razor Entity Framework and stored procedures
我是 MVC 和 Razor 的新手,看过很多这方面的示例和教程,但无法使其正常工作。看起来很简单,但我认为我正在尝试使用存储过程这一事实使一切变得复杂。
我正在尝试使用存储过程和 entity framework.
在 MVC 中创建一些简单的级联下拉菜单
我的实体由以下存储过程组成:
exec prcGetMakes
exec prcGetModels 'BMW'
exec prcGetVariants '1 SERIES 5-DOOR'
我创建了一个名为 VehicleViewModel 的视图模型 class:
public class VehicleViewModel
{
[Display(Name = "Manufacturer")]
public string BrandName { get; set; }
public string BrandID { get; set; }
[Display(Name = "Model")]
public string ModelName { get; set; }
public string ModelID { get; set; }
[Display(Name = "Variant")]
public string VariantName { get; set; }
public IEnumerable<SelectListItem> Manufacturer { get; set; }
public IEnumerable<SelectListItem> Model { get; set; }
public IEnumerable<SelectListItem> Variant { get; set; }
}
我正在使用名为 HomeController.cs
:
的默认控制器 class
public class HomeController : Controller
{
VehicleInfoEntities db = new VehicleInfoEntities();
public ActionResult Index()
{
var app = new VehicleViewModel
{
Manufacturer = GetMakes()
};
return View(app);
}
private IEnumerable<SelectListItem> GetMakes()
{
var list = new VehicleViewModel();
IEnumerable<SelectListItem> manufacturer = from s in db.prcGetMakes(null)
select new SelectListItem
{
Selected = s.ToString() == "Active",
Text = s.BrandName,
Value = s.BrandID
};
return manufacturer;
}
private IEnumerable<SelectListItem> GetModels(string brandName)
{
var list = new VehicleViewModel();
IEnumerable<SelectListItem> models = from s in db.prcGetModels(brandName)
select new SelectListItem
{
Selected = s.ToString() == "Active",
Text = s.ModelName,
Value = s.ModelID
};
return models;
}
private IEnumerable<SelectListItem> GetVariants(string modelName)
{
var list = new VehicleViewModel();
IEnumerable<SelectListItem> variants = from s in db.prcGetVariants(modelName)
select new SelectListItem
{
Selected = s.ToString() == "Active",
Text = s.VariantName,
Value = s.VariantName
};
return variants;
}
}
这是我的看法
@model WebApplication12.Models.VehicleViewModel
@{
ViewBag.Title = "Home Page";
}
@using (Html.BeginForm("Index", "Sample", FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<div class="form-group" style="text-align:left;">
@Html.Label("Manufacturer:", new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.DropDownList("Manufacturer", ViewData["Manufacturer"] as SelectList, new { @class = "form-control" })
</div>
</div><br />
}
期望的结果是
我现在只想知道如何使用 JQuery 使级联 DropDown 工作并筛选每个 DropDown 的选择。
与胖客户端应用程序相比,网络级联下拉列表错综复杂,但这就是网络编程!请记住,javascript 根本不关心您的 MVC 内容。您只需要一个 web 方法(响应 web URL 的东西),它接受一个参数和 returns 正确格式的正确列表。无论它在内部使用什么方法(EF 存储过程、硬编码列表、PHP 读取文本文件)都没有任何区别
要执行您想要的操作,您需要在下拉列表中添加一个 "event handler",它会调用一些 javascript,它会调用您的方法来查找正确的列表,然后填充目标下拉列表使用该列表。
我会在这里放一些示例代码,但是
需要'wiring up'的程度(使用正确的事物名称)
我要做一些假设
我从网上学来的,有些语法可能不正确
因此,首先将一个 onchange 事件处理程序添加到您的下拉列表中,以便当某些内容发生更改时它会触发一些 javascript 代码
@Html.DropDownList("Manufacturer",
ViewData["Manufacturer"] as SelectList,
htmlAttributes:
new { @class = "form-control" ,
@onchange = "refreshModelFromManufacturer()"
}
)
当下拉值改变时它会调用javascript函数refreshModelFromManufacturer()
这里是javascript函数。希望你知道如何添加它。它要求您还需要一个名称为 "Model" 的下拉菜单(您的视图中还没有,所以请添加它):
function refreshModelFromManufacturer()() {
// 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=Manufacturer
src = $("#Manufacturer");
// 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 manufacturer
// The url parameter points at your web method
$.ajax({
type: 'GET',
url: 'Home/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>'
);
})
}
});
}
这是最有可能出错的地方。 Javascript 是无情的,区分大小写,并且有太多容易搞砸的括号。确保你使用的是源代码控制,这样你就可以回滚,因为有时可能无法计算出放错地方的括号,因为代码在 jquery 库深处的某处失败,给你任何线索
最后一件事是您的 Web 方法必须是 Json 类型,以便 ajax 调用有效
public JsonResult GetModels(string brandName)
{
var list = db.prcGetModels(brandName)
return Json(new SelectList(list, "your id column","your label column"));
}
我的代码中唯一的其他区别是实际上像这样定义了一个下拉列表:
@Html.DropDownList("Customer_ID", null, htmlAttributes: new { @class = "form-
control", @onchange = "refreshProjectFromClient()" })
我觉得如果你的ViewBag名字和你的下拉一样,那么你就不需要显式定义viewbag(我的第二个参数是null)
对于调试(因为这不会第一次起作用),请确保您知道如何使用 F12 调试器调试 javascript 以及观察内部网络调用(网络选项卡)。例如,当你 运行 这个时,你应该在网络选项卡
中看到对 Home/GetModels
方法的调用
我是 MVC 和 Razor 的新手,看过很多这方面的示例和教程,但无法使其正常工作。看起来很简单,但我认为我正在尝试使用存储过程这一事实使一切变得复杂。
我正在尝试使用存储过程和 entity framework.
在 MVC 中创建一些简单的级联下拉菜单我的实体由以下存储过程组成:
exec prcGetMakes
exec prcGetModels 'BMW'
exec prcGetVariants '1 SERIES 5-DOOR'
我创建了一个名为 VehicleViewModel 的视图模型 class:
public class VehicleViewModel
{
[Display(Name = "Manufacturer")]
public string BrandName { get; set; }
public string BrandID { get; set; }
[Display(Name = "Model")]
public string ModelName { get; set; }
public string ModelID { get; set; }
[Display(Name = "Variant")]
public string VariantName { get; set; }
public IEnumerable<SelectListItem> Manufacturer { get; set; }
public IEnumerable<SelectListItem> Model { get; set; }
public IEnumerable<SelectListItem> Variant { get; set; }
}
我正在使用名为 HomeController.cs
:
public class HomeController : Controller
{
VehicleInfoEntities db = new VehicleInfoEntities();
public ActionResult Index()
{
var app = new VehicleViewModel
{
Manufacturer = GetMakes()
};
return View(app);
}
private IEnumerable<SelectListItem> GetMakes()
{
var list = new VehicleViewModel();
IEnumerable<SelectListItem> manufacturer = from s in db.prcGetMakes(null)
select new SelectListItem
{
Selected = s.ToString() == "Active",
Text = s.BrandName,
Value = s.BrandID
};
return manufacturer;
}
private IEnumerable<SelectListItem> GetModels(string brandName)
{
var list = new VehicleViewModel();
IEnumerable<SelectListItem> models = from s in db.prcGetModels(brandName)
select new SelectListItem
{
Selected = s.ToString() == "Active",
Text = s.ModelName,
Value = s.ModelID
};
return models;
}
private IEnumerable<SelectListItem> GetVariants(string modelName)
{
var list = new VehicleViewModel();
IEnumerable<SelectListItem> variants = from s in db.prcGetVariants(modelName)
select new SelectListItem
{
Selected = s.ToString() == "Active",
Text = s.VariantName,
Value = s.VariantName
};
return variants;
}
}
这是我的看法
@model WebApplication12.Models.VehicleViewModel
@{
ViewBag.Title = "Home Page";
}
@using (Html.BeginForm("Index", "Sample", FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<div class="form-group" style="text-align:left;">
@Html.Label("Manufacturer:", new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.DropDownList("Manufacturer", ViewData["Manufacturer"] as SelectList, new { @class = "form-control" })
</div>
</div><br />
}
期望的结果是
我现在只想知道如何使用 JQuery 使级联 DropDown 工作并筛选每个 DropDown 的选择。
与胖客户端应用程序相比,网络级联下拉列表错综复杂,但这就是网络编程!请记住,javascript 根本不关心您的 MVC 内容。您只需要一个 web 方法(响应 web URL 的东西),它接受一个参数和 returns 正确格式的正确列表。无论它在内部使用什么方法(EF 存储过程、硬编码列表、PHP 读取文本文件)都没有任何区别
要执行您想要的操作,您需要在下拉列表中添加一个 "event handler",它会调用一些 javascript,它会调用您的方法来查找正确的列表,然后填充目标下拉列表使用该列表。
我会在这里放一些示例代码,但是
需要'wiring up'的程度(使用正确的事物名称)
我要做一些假设
我从网上学来的,有些语法可能不正确
因此,首先将一个 onchange 事件处理程序添加到您的下拉列表中,以便当某些内容发生更改时它会触发一些 javascript 代码
@Html.DropDownList("Manufacturer",
ViewData["Manufacturer"] as SelectList,
htmlAttributes:
new { @class = "form-control" ,
@onchange = "refreshModelFromManufacturer()"
}
)
当下拉值改变时它会调用javascript函数refreshModelFromManufacturer()
这里是javascript函数。希望你知道如何添加它。它要求您还需要一个名称为 "Model" 的下拉菜单(您的视图中还没有,所以请添加它):
function refreshModelFromManufacturer()() {
// 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=Manufacturer
src = $("#Manufacturer");
// 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 manufacturer
// The url parameter points at your web method
$.ajax({
type: 'GET',
url: 'Home/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>'
);
})
}
});
}
这是最有可能出错的地方。 Javascript 是无情的,区分大小写,并且有太多容易搞砸的括号。确保你使用的是源代码控制,这样你就可以回滚,因为有时可能无法计算出放错地方的括号,因为代码在 jquery 库深处的某处失败,给你任何线索
最后一件事是您的 Web 方法必须是 Json 类型,以便 ajax 调用有效
public JsonResult GetModels(string brandName)
{
var list = db.prcGetModels(brandName)
return Json(new SelectList(list, "your id column","your label column"));
}
我的代码中唯一的其他区别是实际上像这样定义了一个下拉列表:
@Html.DropDownList("Customer_ID", null, htmlAttributes: new { @class = "form-
control", @onchange = "refreshProjectFromClient()" })
我觉得如果你的ViewBag名字和你的下拉一样,那么你就不需要显式定义viewbag(我的第二个参数是null)
对于调试(因为这不会第一次起作用),请确保您知道如何使用 F12 调试器调试 javascript 以及观察内部网络调用(网络选项卡)。例如,当你 运行 这个时,你应该在网络选项卡
中看到对Home/GetModels
方法的调用