我有以下视图模型:
Public Class MyViewModel
Public Property SelectedIDs As List(Of Integer)
Public Property FilterListItems As SelectList
Public Property SelectionListItems As SelectList
End Class
对于SelectedIDs属性中的每个整数,我需要显示一个用FilterListItems属性中的项填充的下拉列表和一个用SectionListItems属性中的项填充的下拉列表,并且需要在SectionListItems下拉列表中选择SelectedID值。当用户进行更改时,带有FilterListItems的下拉列表将过滤带有SectionListItems的下拉列表中的项目。这将通过jQuery完成,所以我需要两个下拉列表的in,以便将其连接起来。用户还可以在页面上添加另一组下拉列表。他们可以添加的下拉列表的组数没有限制。
当用户点击“保存”按钮时,需要将填充有SectionListItems的每个下拉列表中的选定项值发送回服务器并保存下来。
在视图上渲染它的最佳方式是什么?根据我所看到的,我可以执行for each循环&手动呈现下拉列表,或者我可以呈现包含两个下拉列表的部分视图。如何确保ID不同&将它们连接到jQuery,以便过滤器下拉列表与正确的选择项下拉列表一起工作?
当用户提交表单时,如何将用户的选择传递回我的控制器?我应该使用jQuery来找到所有的下拉列表,创建一个JSON对象并提交,还是可以用MVC来完成?
用户如何在页面上添加另一组下拉列表?我已经看到你可以通过jQuery使用克隆方法,但是列表需要重新加载,if需要更新,等等。如果我使用jQuery和某种模板,情况也是如此。此外,我还看到可以使用Ajax.ActionLink呈现另一个局部视图,这似乎是一种更好的方法,但是它如何分配正确的ID&我如何将这些ID连接到jQuery?也许只是将它连接到部分文档中,准备好了吗?
发布于 2011-11-18 16:38:05
我可能会稍微调整一下视图模型:
public class MyViewModel
{
public IEnumerable<ItemViewModel> Items { get; set; }
}
public class ItemViewModel
{
public int SelectedFilterId { get; set; }
public IEnumerable<SelectListItem> FilterListItems { get; set; }
public int SelectedId { get; set; }
public IEnumerable<SelectListItem> SelectionListItems { get; set; }
}
现在我们有了包含项目列表的主视图模型,其中每个项目分别表示用于过滤和选择的两个下拉列表。然后我们有两个概念要在这里解决:
史蒂夫·桑德森在this great post中提到了第一点。
让我们来解决第二点。因此,我们将有一个具有4个操作的控制器:
最初加载页面时调用
因此,让我们将其付诸实践:
public ActionResult Index()
{
var filters = ... fetch from repo and map to view model
var selectionItems = ... fetch from repo and map to view model
var model = new MyViewModel
{
// TOOO: fetch from repo and map to view model
Items = new[]
{
new ItemViewModel
{
SelectedFilterId = 1,
FilterListItems = filters,
SelectionListItems = selectionItems
},
new ItemViewModel
{
SelectedFilterId = 3,
FilterListItems = filters,
SelectionListItems = selectionItems
},
}
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
// TODO: process the selected values here
...
}
public ActionResult Filter(int filterId)
{
return Json(_repository.GetSelectionItems(filterId));
}
public ActionResult BlankEditorRow()
{
var filters = ... fetch from repo and map to view model
var selectionItems = ... fetch from repo and map to view model
var model = new ItemViewModel
{
SelectedFilterId = 1,
FilterListItems = filters,
SelectionListItems = selectionItems
};
return PartialView("~/views/home/editortemplates/itemviewmodel.cshtml", model);
}
下一步是定义~/Views/Home/Index.cshtml
视图:
@model MyViewModel
@using (Html.BeginForm())
{
<ul id="editorRows">
@Html.EditorFor(x => x.Items)
</ul>
<button type="submit">OK</button>
}
@Html.ActionLink("Add another group of ddls", "BlankEditorRow", null, new { id = "addItem" })
以及对应的编辑器模板(~/Views/Home/EditorTemplates/ItemViewModel.cshtml
):
@model ItemViewModel
<li>
<div>
@using (Html.BeginCollectionItem("items"))
{
@Html.DropDownListFor(
x => x.SelectedFilterId,
new SelectList(Model.FilterListItems, "Value", "Text", Model.SelectedFilterId),
new { @class = "filter", data_filter_url = Url.Action("Filter") }
)
@Html.DropDownListFor(
x => x.SelectedId,
new SelectList(Model.SelectionListItems, "Value", "Text", Model.SelectedId),
new { @class = "selection" }
)
}
</div>
</li>
最后一步是连接级联下拉列表和使用javascript动态添加组的可能性。所以在一个单独的js文件中:
var filterChange = function () {
$('ul .filter').unbind('change').bind('change', function () {
$.ajax({
url: $(this).data('filter-url'),
type: 'GET',
cache: false,
data: { filterId: $(this).val() },
context: { selectionDdl: $(this).closest('li').find('.selection') },
success: function (items) {
var selectionDdl = this.selectionDdl;
selectionDdl.empty();
$.each(items, function (index, item) {
selectionDdl.append($('<option/>', {
value: item.ID,
text: item.Name
}));
});
}
});
});
};
$(function () {
filterChange();
$('#addItem').click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) {
$('#editorRows').append(html);
filterChange();
}
});
return false;
});
});
https://stackoverflow.com/questions/8170194
复制相似问题