我有一个网站,其中所有页面都需要一个列出国家/地区的下拉列表和另一个包含基于所选国家/地区的子数据的下拉列表。
我对这篇文章采取了类似的方法:
MVC 3 布局页面、Razor 模板和 DropdownList
所以我需要如下功能:
- 1.) 上下文控件始终出现在布局页面上(国家下拉列表和它的依赖)
- 2.) 当国家下拉列表改变时,用与该国家相关的数据填充第二个下拉列表。
目前我有一个 UserContextController 处理获取和发布请求并返回部分视图:
来自 UserContextController 的索引操作:
[HttpPost]
public ActionResult Index(UserContextViewModel userContext)
{
//CurrentUserContext is a Session wrapper to store the selections from the dropdowns
//in application scope for ease of reference. This is accessed in a base controller all controllers inherit from
this.CurrentUserContext.SetCountryContext(this.countryRepository.GetList().SingleOrDefault(c => c.Id == userContext.CountryId));
if (userContext.TerritoryId > 0)
{
//return partial view containing model data and select list data
return PartialView("ContextControls", new UserContextViewModel(this.countryRepository.GetList(),
AvailableTerritories,
CurrentUserContext.CurrentCountry,
CurrentUserContext.CurrentTerritory));
}
我的布局页面引用了 UserContextController 和 Index 操作:
<header>
<div class="content-wrapper">
<a href=".">HOME</a>
@Html.Action("Index", "UserContext")
</div>
</header>
添加到布局页面的部分视图中的下拉列表有一些 jquery,当它们发生变化时会调用一个 http post 到 UserContextController(形状为 UserContextViewModel 模式):
//_targetUrl is: /UserContext
$.post(_targetUrl, { CountryId: $('#CountryId').val(),TerritoryId:$('#TerritoryId').val() }, function (result) { });
查看设置所选项目的模型代码:
public IEnumerable<SelectListItem> CountrySelectItems
{
get
{
int selectedCountryId = this.selectedCountry==null ? 0 : this.selectedCountry.Id;
return new SelectList(this.countries, "Id", "Name",selectedCountryId);
}
}
设置所选国家的 ViewModel 的构造函数:
public UserContextViewModel(IEnumerable<Country> countries, IEnumerable<Territory> territories,Country selectedCountry,Territory selectedTerritory)
{
this.countries = countries;
this.territories = territories;
this.selectedCountry = selectedCountry;
this.selectedTerritory = selectedTerritory;
}
部分观点:
<p>
<label>Country:</label>
@Html.DropDownList("CountryId", @Model.CountrySelectItems, new { @class = "context-control" })
</p>
用于保存值集的用户上下文会话包装器:
protected IUserContext CurrentUserContext
{
get
{
const string contextKey = "USER_CONTEXT";
if (HttpContext.Session[contextKey] == null)
{
HttpContext.Session.Add(contextKey, new UserContext());
}
return HttpContext.Session[contextKey] as IUserContext;
}
}
因此,这有效并更新了我的 UserContext 中的值,但国家下拉列表从不设置所选国家,并且始终默认为列表中的第一项。即包含英国和德国。选择德国 -> 发布到控制器 -> 设置所选值 -> 下拉菜单仍在英国!
当这些下拉菜单发生变化时,UI 应该返回到起始页面,因为它会影响 UI 中呈现的数据,并且用户需要注意“上下文变化”(例如,他们不会为不同的国家/地区上下文添加数据) .
有趣的是,在 Fiddler 中,当下拉列表更改时,我可以看到返回的响应包含整个布局页面,并且下拉 HTML 具有正确选择的选项!
我认为我的方法是错误的……有没有人实现了类似的功能?我是从最近完成的生产 WebForms 项目的角度来看的,该项目通过用户控件执行相同的操作,并希望在 MVC 中生成 PoC,但惨遭失败!
我想我需要通过 Angular 将下拉列表驱动到 WebAPI 请求和上下文设置。