Asp.net mvc 3 在布局中共享下拉列表以在所有视图中使用的方法是什么?

Asp.net mvc 3 在布局中共享下拉列表以在所有视图中使用的方法是什么?,asp.net-mvc-3,razor,Asp.net Mvc 3,Razor,我越来越熟悉MVC3和RAZOR视图引擎。我有一个关于页面布局和共享控件的问题 假设我在主布局中定义了一个标题部分。在这个标题中有一个下拉列表,我需要用项目名称填充它。此下拉列表将用作整个站点的上下文,并显示在所有页面上。例如,如果用户从下拉列表中选择“项目A”,则站点的所有视图都将基于“项目A”。因为这个下拉控件是相当静态的,并且被整个站点使用,所以在哪里放置代码以将所有项目拉到下拉列表中显示是最好的?偏袒地看?在HTML助手中?另一个想法是,如果用户选择一个新值,他们将被带到新选择项目的仪表

我越来越熟悉MVC3和RAZOR视图引擎。我有一个关于页面布局和共享控件的问题


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

我们刚刚在一个项目上做了类似的事情

首先,你不能真的把它放在一个部分中,因为你必须把这个部分放在每个视图中,你可以把它放在一个部分中,但是你仍然必须从每个视图调用它

其次,你不能把它放在布局页面中,因为布局页面没有传递任何类型的模型。因此,我创建了一个html帮助程序,并在布局页面中引用了它。有很多关于创建html助手的教程,所以我不在这里介绍代码。但实际上,在html助手中,您可以进行数据库调用以获取所有项目。然后,您可以在html帮助器中使用字符串生成器创建一个选择列表,并将其返回到布局页面。然后,我们使用jquery将一个on change事件添加到选择列表中。当选择列表更改时,它将加载一个新页面。例如,在您的选择列表中,每个项目的值可以是项目id,然后在更改时,它会将它们重定向到一个页面,如/Projects/View?id=234,其中234是您的项目id

所以需要研究的东西。1.创建HTML助手2。JQUERY更改事件


这会让你走上正确的方向。如果您需要任何其他帮助,请告诉我,我可以发布一些代码。

您可以与帮助者一起使用子操作。因此,首先定义一个视图模型:

public class ProjectViewModel
{
    [DisplayName("Project name")]
    public string ProjectId { get; set; }
    public IEnumerable<SelectListItem> ProjectNames { get; set; }
}
然后是相应的视图(
~/views/projects/index.cshtml
):

现在剩下的就是在
\u Layout.cshtml
中呈现这个小部件:

@model ProjectViewModel

@Html.LabelFor(x => x.ProjectId)
@Html.DropDownListFor(
    x => x.ProjectId, 
    Model.ProjectNames,
    new {
        id = "projects",
        data_url = Url.Action("SomeAction", "SomeController")
    }
)
@Html.Action("Index", "Products", new { projectid = Request["projectId"] })
现在我们可以放置一些javascript,这样当用户决定更改选择时,他将被重定向到其他操作:

$(function() {
    $('#projects').change(function() {
        var url = $(this).data('url');
        var projectId = encodeURIComponent($(this).val());
        window.location.href = url + '?projectid=' + projectId;
    });
});
另一种可能是将下拉列表放在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",
        }
    )
}
因此,在javascript中,我们不必担心在选择更改时构建URL,只需触发包含表单的提交:

$(function() {
    $('#projects').change(function() {
        $(this).closest('form').submit();
    });
});

是的,这是在所有页面上呈现通用HTML的正确解决方案。在布局页面中使用Html.Action,我只能建议另外一个改进:使用[OutputCache],在从布局调用的Action方法上使用正确的值。它极大地提高了渲染时间。@Darin需要控制器吗?我可以有一个生成下拉列表的HTML.helper方法吗?对于这种方法,我需要编写一个单独的控制器和一个视图模型。我只是问我是否使用HTML助手,我可以避免这种情况。如果我错了,请纠正我。
$(function() {
    $('#projects').change(function() {
        $(this).closest('form').submit();
    });
});