【发布时间】:2017-12-02 01:49:59
【问题描述】:
我无法根据我希望编辑的所选客户 ID 从数据库中检索/显示 CityId 值到 City 下拉列表。
当我选择要编辑的客户时,它会正确填充数据库中的数据,但城市下拉列表除外。城市下拉列表将显示“选择城市”以及与州下拉列表中的州相关的所有城市。
如果我选择另一个州,那么它会正确加载所选州的所有城市。
问题是它没有像我第一次根据所选客户 ID 加载页面时那样显示城市下拉列表的城市值。
我是 jQuery/AJAX 的新手,有人帮我编写级联下拉列表的 jQuery 代码。
我在下面提供了我现在正在使用的 ViewModel、Controller 和 Edit View:
客户模型
public class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int CityId { get; set; }
public City City { get; set; }
public int LocalityId { get; set; }
public Locality Locality { get; set; }
public int SubLocalityId { get; set; }
public SubLocality SubLocality { get; set; }
}
城市模型
public class City
{
public int ID { get; set; }
public string Name { get; set; }
public List<Customer> Customers { get; set; }
public List<Locality> Localities { get; set; }
}
局部模型
public class Locality
{
public int ID { get; set; }
public string Name { get; set; }
public int CityId { get; set; }
public City City { get; set; }
public List<Customer> Customers { get; set; }
public List<SubLocality> SubLocalities { get; set; }
}
子区域模型
public class SubLocality
{
public int ID { get; set; }
public string Name { get; set; }
public int LocalityId { get; set; }
public Locality Locality { get; set; }
public List<Customer> Customers { get; set; }
}
WebAppDbContext
public class WebAppDbContext : DbContext
{
public WebAppDbContext(DbContextOptions<WebAppDbContext> options) : base(options)
{ }
public DbSet<Customer> Customers { get; set; }
public DbSet<City> Cities { get; set; }
public DbSet<Locality> Localities { get; set; }
public DbSet<SubLocality> SubLocalities { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>()
.HasKey(c => c.CustomerId);
modelBuilder.Entity<Customer>()
.Property(c => c.FirstName)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<Customer>()
.Property(c => c.LastName)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<City>()
.HasKey(ci => ci.ID);
modelBuilder.Entity<City>()
.Property(ci => ci.Name)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<City>()
.HasMany(ci => ci.Customers)
.WithOne(c => c.City)
.HasForeignKey(c => c.CityId);
modelBuilder.Entity<City>()
.HasMany(l => l.Localities)
.WithOne(ci => ci.City)
.HasForeignKey(ci => ci.CityId);
modelBuilder.Entity<Locality>()
.HasKey(l => l.ID);
modelBuilder.Entity<Locality>()
.Property(l => l.Name)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<Locality>()
.HasMany(l => l.Customers)
.WithOne(c => c.Locality)
.HasForeignKey(c => c.LocalityId);
modelBuilder.Entity<Locality>()
.HasMany(sl => sl.SubLocalities)
.WithOne(l => l.Locality)
.HasForeignKey(l => l.LocalityId);
modelBuilder.Entity<SubLocality>()
.HasKey(sl => sl.ID);
modelBuilder.Entity<SubLocality>()
.Property(sl => sl.Name)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<SubLocality>()
.HasMany(sl => sl.Customers)
.WithOne(c => c.SubLocality)
.HasForeignKey(c => c.SubLocalityId);
}
}
CustomerFormVM
public class CustomerFormVM
{
[Required(ErrorMessage = "Please enter a First Name")]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Please enter a Last Name")]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required(ErrorMessage = "Please select a city")]
[Display(Name = "City")]
public int? SelectedCity { get; set; }
[Required(ErrorMessage = "Please select a locality")]
[Display(Name = "Locality")]
public int? SelectedLocality { get; set; }
[Required(ErrorMessage = "Please select a sub locality")]
[Display(Name = "Sub Locality")]
public int? SelectedSubLocality { get; set; }
public SelectList CityList { get; set; }
public SelectList LocalityList { get; set; }
public SelectList SubLocalityList { get; set; }
}
客户控制器
public class CustomersController : Controller
{
private readonly WebAppDbContext _context;
public CustomersController(WebAppDbContext context)
{
_context = context;
}
// GET: Customers
public async Task<IActionResult> Index()
{
var webAppDbContext = _context.Customers.Include(c => c.City).Include(c => c.Locality).Include(c => c.SubLocality);
return View(await webAppDbContext.ToListAsync());
}
// GET: Customers/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var customer = await _context.Customers
.Include(c => c.City)
.Include(c => c.Locality)
.Include(c => c.SubLocality)
.SingleOrDefaultAsync(m => m.CustomerId == id);
if (customer == null)
{
return NotFound();
}
return View(customer);
}
// GET: Customers/Create
[HttpGet]
public ActionResult Create()
{
CustomerFormVM model = new CustomerFormVM();
ConfigureViewModel(model);
return View(model);
}
// POST: Customers/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerFormVM vm)
{
if (ModelState.IsValid)
{
var customer = new Customer();
{
customer.FirstName = vm.FirstName;
customer.LastName = vm.LastName;
customer.CityId = vm.SelectedCity.Value;
customer.LocalityId = vm.SelectedLocality.Value;
customer.SubLocalityId = vm.SelectedSubLocality.Value;
}
_context.Customers.Add(customer);
_context.SaveChanges();
return RedirectToAction("Index");
}
else
{
ConfigureViewModel(vm);
return View(vm);
}
}
[HttpGet]
public JsonResult FetchLocalities(int ID)
{
var data = _context.Localities
.Where(l => l.CityId == ID)
.Select(l => new { val = l.ID, text = l.Name });
return Json(data);
}
[HttpGet]
public JsonResult FetchSubLocalities(int ID)
{
var data = _context.SubLocalities
.Where(l => l.LocalityId == ID)
.Select(l => new { val = l.ID, text = l.Name });
return Json(data);
}
private void ConfigureViewModel(CustomerFormVM model)
{
List<City> cities = _context.Cities.ToList();
model.CityList = new SelectList(cities, "ID", "Name");
if (model.SelectedCity.HasValue)
{
IEnumerable<Locality> localities = _context.Localities.Where(l => l.CityId == model.SelectedCity.Value);
model.LocalityList = new SelectList(localities, "ID", "Name");
}
else
{
model.LocalityList = new SelectList(Enumerable.Empty<SelectListItem>());
}
if (model.SelectedLocality.HasValue)
{
IEnumerable<SubLocality> subLocalities = _context.SubLocalities.Where(l => l.LocalityId == model.SelectedLocality.Value);
model.SubLocalityList = new SelectList(subLocalities, "ID", "Name");
}
else
{
model.SubLocalityList = new SelectList(Enumerable.Empty<SelectListItem>());
}
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var customervm = new CustomerFormVM();
{
Customer customer = _context.Customers.SingleOrDefault(c => c.CustomerId == id);
if (customer == null)
{
return NotFound();
}
customervm.CustomerId = customer.CustomerId;
customervm.FirstName = customer.FirstName;
customervm.LastName = customer.LastName;
}
return View(customervm);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomerFormVM vmEdit)
{
if (ModelState.IsValid)
{
Customer customer = _context.Customers.SingleOrDefault(c => c.CustomerId == vmEdit.CustomerId);
if (customer == null)
{
return NotFound();
}
customer.FirstName = vmEdit.FirstName;
customer.LastName = vmEdit.LastName;
_context.Entry(customer).State = EntityState.Modified;
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(vmEdit);
}
// GET: Customers/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var customer = await _context.Customers
.Include(c => c.City)
.Include(c => c.Locality)
.Include(c => c.SubLocality)
.SingleOrDefaultAsync(m => m.CustomerId == id);
if (customer == null)
{
return NotFound();
}
return View(customer);
}
// POST: Customers/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var customer = await _context.Customers.SingleOrDefaultAsync(m => m.CustomerId == id);
_context.Customers.Remove(customer);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
private bool CustomerExists(int id)
{
return _context.Customers.Any(e => e.CustomerId == id);
}
}
创建视图
@using (Html.BeginForm("Create", "Customers"))
{
<div class="form-group">
@Html.LabelFor(c => c.FirstName)
@Html.TextBoxFor(c => c.FirstName, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(c => c.LastName)
@Html.TextBoxFor(c => c.LastName, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.SelectedCity)
@Html.DropDownListFor(m => m.SelectedCity, Model.CityList, "Please select", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SelectedCity)
</div>
<div class="form-group">
@Html.LabelFor(m => m.SelectedLocality)
@Html.DropDownListFor(m => m.SelectedLocality, Model.LocalityList, "", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SelectedLocality)
</div>
<div class="form-group">
@Html.LabelFor(m => m.SelectedSubLocality)
@Html.DropDownListFor(m => m.SelectedSubLocality, Model.SubLocalityList, "", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SelectedSubLocality)
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-default" />
</div>
}
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
var localityUrl = '@Url.Action("FetchLocalities")';
var subLocalityUrl = '@Url.Action("FetchSubLocalities")';
var localities = $('#SelectedLocality');
var subLocalities = $('#SelectedSubLocality');
$('#SelectedCity').change(function() {
localities.empty();
subLocalities.empty();
$.getJSON(localityUrl, { ID: $(this).val() },function (data) {
if (!data) {
return;
}
localities.append($('<option></option>').val('').text('Please select'));
$.each(data, function(index, item) {
localities.append($('<option></option>').val(item.val).text(item.text));
});
});
})
$('#SelectedLocality').change(function() {
subLocalities.empty();
$.getJSON(subLocalityUrl, { ID: $(this).val() },function (data) {
if (!data) {
return;
}
subLocalities.append($('<option></option>').val('').text('Please Select'));
$.each(data, function(index, item) {
subLocalities.append($('<option></option>').val(item.val).text(item.text));
});
});
})
</script>
}
编辑视图
@using (Html.BeginForm("Edit", "Customers"))
{
<div class="form-group">
@Html.LabelFor(c => c.FirstName)
@Html.TextBoxFor(c => c.FirstName, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(c => c.LastName)
@Html.TextBoxFor(c => c.LastName, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.SelectedCity)
@Html.DropDownListFor(m => m.SelectedCity, Model.CityList, "Please select", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SelectedCity)
</div>
<div class="form-group">
@Html.LabelFor(m => m.SelectedLocality)
@Html.DropDownListFor(m => m.SelectedLocality, Model.LocalityList, "", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SelectedLocality)
</div>
<div class="form-group">
@Html.LabelFor(m => m.SelectedSubLocality)
@Html.DropDownListFor(m => m.SelectedSubLocality, Model.SubLocalityList, "", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SelectedSubLocality)
</div>
@Html.HiddenFor(m => m.CustomerId)
<div class="form-group">
<input type="submit" value="Save" class="btn btn-default" />
</div>
}
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
var localityUrl = '@Url.Action("FetchLocalities")';
var subLocalityUrl = '@Url.Action("FetchSubLocalities")';
var localities = $('#SelectedLocality');
var subLocalities = $('#SelectedSubLocality');
$('#SelectedCity').change(function() {
localities.empty();
subLocalities.empty();
$.getJSON(localityUrl, { ID: $(this).val() },function (data) {
if (!data) {
return;
}
localities.append($('<option></option>').val('').text('Please select'));
$.each(data, function(index, item) {
localities.append($('<option></option>').val(item.val).text(item.text));
});
});
})
$('#SelectedLocality').change(function() {
subLocalities.empty();
$.getJSON(subLocalityUrl, { ID: $(this).val() },function (data) {
if (!data) {
return;
}
subLocalities.append($('<option></option>').val('').text('Please Select'));
$.each(data, function(index, item) {
subLocalities.append($('<option></option>').val(item.val).text(item.text));
});
});
})
</script>
}
【问题讨论】:
-
您确定 JQUERY 工作正常吗?在视图中,我在部分脚本中放置了这个标记 (更改正确的版本)。
-
是的,jQuery 代码在我这边工作。 jQuery 2.2.0
-
我的 Create 方法有相同的 jQuery 代码,它工作正常,唯一的问题是我无法根据为 Edit 方法选择的 CustomerId 检索 CityId。
-
为什么需要这个`$("#StateId").trigger('change');`?您的页面将使用您拥有的服务器代码在下拉列表中加载所选城市。
-
建议您参考this answer了解如何正确处理
标签: c# asp.net asp.net-mvc