【问题标题】:Reusing a view in another view with parameters in ASP.NET MVC在 ASP.NET MVC 中使用参数重用另一个视图中的视图
【发布时间】:2012-07-14 08:34:08
【问题描述】:

作为 ASP.NET MVC 的新手,我已经看到它在代码重用和可维护性方面的一些好处。在询问previous question on routing 时,我对我的示例有另一个想法,但不确定如何实现它。

问题:如何在单独的页面中重复使用我的问题视图和控制器,以及为某些事情(例如要显示多少个问题)设置参数?

示例:在我的网络应用程序中说我想显示问题列表。这些问题按项目分组。因此,如果您访问 www.example.com/projectname/issues,您会看到该项目的问题列表,如果您访问 www.example.com/issues,您会看到所有项目的所有问题。我想做的是,如果您访问 www.example.com/projectname,您会看到有关该项目的一些信息,包括最近提交的 10 个问题。

如何重复使用此问题代码?我看到我有 Partial View 的选项,但是当我实现它时,我不确定如何将任何代码路由到它。在 Web 窗体中,您可以制作一个 ASP.net 控件,在后面的代码中设置一些参数,然后将此控件嵌入到其他地方。

到目前为止,我发现的一些示例要么缺乏完整的实现(不仅仅是在其他页面中添加一些 HTMl),看起来像是在 ASP.NET MVC 3 中似乎不适合我的旧 MVC 代码,并且缺乏允许我设置参数并展示这种类型的重用。

我的术语在这里可能并不完全正确。如果有的话,我正在尝试找到最好的(阅读 MVC)方法来复制 ASP.net Web Forms User Controls 之类的东西。例如,在“主”问题列表以及问题“小部件”上重复使用我的“问题”代码(HTML 和 C#)

【问题讨论】:

  • 你可以用你的路线变魔术。我书中的第一步是为 {project}/{controller}/{action} 注册一个路由并创建一个路由约束来验证“项目”是否存在,无论是 ID 还是字符串。从那里我将创建一个基本控制器并使用 Initalize 事件从路由值中读取数据并填充项目。从那里您可以读取操作中的属性,以将项目(ID 或名称)传递给您用来过滤问题的对象。
  • 我的困惑在于如何重用这个问题代码。我已经有类似的东西用于路由以缩小问题范围。现在更重要的是如何在项目页面上显示更小的问题列表。
  • 我相信您正在寻找 PartialView

标签: c# asp.net-mvc asp.net-mvc-3


【解决方案1】:

跳过在视图中编写代码并自行访问数据的诱惑。这包括使用 RenderAction 等内置函数。即使 RenderAction “返回”以执行另一个控制器,但这并不意味着视图没有自行执行操作,这可以说打破了 MVC 方法,其中视图应该什么都不做而模型应该包含 视图所需的一切

您可以做的是为您的问题列表页面发回一个模型,其中包含一个包含问题列表的属性:

public class IssueListModel {
    public List<Issue> Issues { get; set; }
}

将其填充到您的问题列表操作中:

public ActionResult IssueList(string projectName) // projectName may be null
{
    var issueListModel = new IssueListModel();

    issueListModel.Issues = SomeRepository.GetIssues(projectName); // whatever you need to send...


    return View(issueListModel);
}

然后在您的列表页面上,您可以循环浏览它:

@foreach (var issue in Model.Issues) {
    <div>@issue.IssueName</div>
}

或者您可以将问题集合发送到局部视图:

@Html.RenderPartial("IssueList", Model.Issues)

您可以键入局部视图以期望 List 作为模型:

@model List<MyProject.Models.Issue>

...然后在局部视图中循环遍历它,这一次对模型本身进行 foreach:

@foreach (var issue in Model) {
    <div>@issue.IssueName</div>
}

然后你可以做的是为你的项目详细视图创建一个单独的模型,该模型还包含一个包含问题的属性:

public class ProjectDetailModel {
    public Project Project { get; set; }
    public List<Issue> Issues { get; set; }
    public string Whatever { get; set; }
}

在控制器中,您可以使用与在列表控制器中填充的相同功能来填充此列表:

public ActionResult ProjectDetail(string projectName)
{
    var projectDetailModel = new ProjectDetailModel();

    projectDetailModel.Issues = SomeRepository.GetIssues(projectName, 10); // whatever you need to send


    return View(projectDetailModel);
}

然后您可以在 ProjectDetail 视图中重复使用完全相同的局部视图:

@Html.RenderPartial("IssueList", Model.Issues)

一个很长的答案,但我希望这就是你要找的!

【讨论】:

  • 这很接近,但是当我遵循最后一个大“传递到字典的模型项的类型是'System.Web.Mvc.ViewResult',但是这个字典需要一个'Models.Issues' 类型的模型项"
  • 另外,在这种情况下,是否会触发两个操作,一个用于“项目”页面,然后一个用于“问题”部分视图?我似乎在网上找不到任何像这样的好例子,其中部分视图有自己的代码。
  • 啊,我想通了!这是因为我返回的是 ActionResult 而不是实际的 Object。它现在可以正常工作了。在这种情况下,我希望所有内容都应该进入 Object 与 ViewBag?
  • RenderPartial 不会触发其他操作,因此它只能使用来自主页操作的数据。是的,当您在局部视图上声明 @model 时,您需要传入该确切对象才能使其工作。祝你好运!
【解决方案2】:

如果您只想重用表示逻辑,您可以使用部分视图。如果您还想重用控制器的逻辑,则必须使用结合局部视图的子操作。

创建一个控制器

public class IssuesController : Controller
{
    [ChildActionOnly]
    public PartialViewResult List(string projectName, int issueCount = 0)
    {
        IEnumerable<Issue> issueList = new List<Issue>();

        // Here load appropriate issues into issueList

        return PartialView(issueList);
    }
}

不要忘记在文件夹 Issues 中创建名为 List 的适当局部视图。

最后在你的项目视图中使用这一行

@{ Html.RenderAction("List", "Issues", new { projectName = "Px", issueCount = 10 } ); }

问题列表视图中的这一行

@{ Html.RenderAction("List", "Issues", new { projectName = "Px" } ); }

【讨论】:

    【解决方案3】:

    在您的控制器方法中,以命名的方式返回视图,而不仅仅是 View()

    即……

    public ViewResult IssueView1()
    { return View("Issue");}
    
    public ViewResult IssueView2()
    {return View("Issue");}
    

    【讨论】:

    • 这解决了如何从一个单独的 action 显示另一个视图。它not 解决了如何从单独的view 中显示另一个视图。
    • 好吧,我的术语可能不正确。即使使用它,我也需要了解更多关于如何将参数传递给其他子视图、如果我使用多个子视图等的信息
    • 你需要通过什么?如果您担心通过项目,它可以在 ViewContext RouteData 值中使用。如果您使用内置的 Html 或 Url 助手来生成链接等内容,则路由值将已经存在,并且生成的 URL 将具有正确的 URL 结构
    • 我正在寻找的是要显示多少问题的参数。如果没有参数,则使用默认值。但如果是参数,请使用它。然后,如何在另一个已经在做自己的工作的视图中使用它(例如,问题是一部分,“项目”页面还可能列出当前用户、统计信息等,同时还可以重用其中的一些代码)
    • 使用 ViewBag 或 ViewData 共享它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    • 2013-06-14
    相关资源
    最近更新 更多