有什么方法可以在布局中共享下拉列表以便在所有视图中使用?

DDi*_*ita 5 razor asp.net-mvc-3

我对MVC 3和RAZOR视图引擎越来越熟悉了.我有关于页面上的布局和共享控件的问题.

假设我的主布局中定义了标题部分.在该标题中是一个下拉列表,我需要填充项目名称.此下拉列表将作为整个站点的上下文,并显示在所有页面上.例如,如果用户从下拉列表中选择"项目A",则该站点的所有视图都将基于"项目A".由于此下拉控件是相当静态的并且由整个站点使用,因此将代码放在下拉列表中以显示所有项目的最佳位置在哪里?在部分视图?在HTML助手?另一个想法是,如果用户选择新值,他们将被带到该新选择的项目的仪表板或类似页面.我试图弄清楚如何在网站的每个页面上重用这个控件,而不必在每个可能的控制器中连接它.

Dar*_*rov 13

您可以使用子操作以及Html.Action帮助程序.首先,您要定义一个视图模型:

public class ProjectViewModel
{
    [DisplayName("Project name")]
    public string ProjectId { get; set; }
    public IEnumerable<SelectListItem> ProjectNames { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后一个控制器:

public class ProjectsController: Controller
{
    private readonly IProjectsRepository _repository;
    public ProjectsController(IProjectsRepository repository)
    {
        _repository = repository;
    }

    public ActionResult Index(string projectId)
    {
        var projects = _repository.GetProjects();
        var model = new ProjectViewModel
        {
            ProjectId = projectId,
            ProjectNames = projects.Select(x => new SelectListItem
            {
                Value = x.Id,
                Text = x.Name
            })
        };
        return PartialView(model);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后是相应的视图(~/views/projects/index.cshtml):

@model ProjectViewModel

@Html.LabelFor(x => x.ProjectId)
@Html.DropDownListFor(
    x => x.ProjectId, 
    Model.ProjectNames,
    new {
        id = "projects",
        data_url = Url.Action("SomeAction", "SomeController")
    }
)
Run Code Online (Sandbox Code Playgroud)

现在剩下的就是将这个小部件呈现在_Layout.cshtml:

@Html.Action("Index", "Products", new { projectid = Request["projectId"] })
Run Code Online (Sandbox Code Playgroud)

现在我们可以放一些javascript,这样当用户决定更改选择时,他会被重定向到其他一些动作:

$(function() {
    $('#projects').change(function() {
        var url = $(this).data('url');
        var projectId = encodeURIComponent($(this).val());
        window.location.href = url + '?projectid=' + projectId;
    });
});
Run Code Online (Sandbox Code Playgroud)

另一种可能性是将下拉列表放在HTML表单中:

@model ProjectViewModel
@using (Html.BeginForm("SomeAction", "SomeController", FormMethod.Get))
{
    @Html.LabelFor(x => x.ProjectId)
    @Html.DropDownListFor(
        x => x.ProjectId, 
        Model.ProjectNames,
        new {
            id = "projects",
        }
    )
}
Run Code Online (Sandbox Code Playgroud)

所以在javascript中我们不必担心在选择更改时构建url并只是触发包含表单提交:

$(function() {
    $('#projects').change(function() {
        $(this).closest('form').submit();
    });
});
Run Code Online (Sandbox Code Playgroud)