【问题标题】:In a MVC/MVP framework, how to deal with pages that are not associated with a single model / controller?在 MVC/MVP 框架中,如何处理与单个模型/控制器无关的页面?
【发布时间】:2013-11-14 14:30:39
【问题描述】:

我们通常在框架文档中看到的是简单的类似博客的应用程序,其中每个页面仅与一个模型和一个控制器相关。

如何处理最常见的单个页面必须显示来自不同模型的信息的情况?

示例:

显示以下内容的社交网络主页:

  • 最近的用户帖子
  • 最近的用户
  • 来自管理员的消息
  • 最常玩的游戏

这是否应该由单个控制器处理,该控制器从不同模型加载所有这些信息并将其发送到可能分解为部分/元素的视图?

有人在另一个问题中说,我可以为这样的页面创建类似 HomePageController 的东西。如果所有这些信息都应该显示在网站上所有页面的侧边栏中,我该如何处理?

【问题讨论】:

    标签: model-view-controller architecture frameworks mvp


    【解决方案1】:

    通常,您将收集所有不同类型的数据并将其传递给视图一起

    MVC 框架通常提供一些方法来将请求 URL(例如 /offers?id=5)映射到控制器(或其方法)。

    假设您想在主页上显示一些数据。
    为此,您将首先定义从 URL /home 到某个特定控制器的映射,例如 HomePageController。 使用您的示例数据,您将在控制器中拥有类似的内容(在处理请求的方法中):

    model.add(dao.getRecentUserPosts());
    model.add(dao.getRecentUsers());
    model.add(dao.getNewsFromAdmins());
    model.add(dao.getMostPlayedGames());
    
    render("viewName", model);
    

    根据对映射到此特定控制器的某些地址的请求,您将从数据访问对象 (dao) 中获取不同类型的数据,并将它们添加到您的 model
    一旦model 填充了数据,您可以将其传递给视图(= render 视图与此model),并在视图中以任何您想要的方式显示它。

    我希望您现在清楚基本流程。

    参考@BeK 的回答
    处理需要更长时间的请求总是需要单独的方法。您可以选择异步加载此部分,您可以(并且可能会)尝试尽可能多地缓存。

    加载侧边栏:
    大多数 MVC 框架为您的视图提供某种“基本模板”。
    这意味着您可以定义显示在每个页面上的视图的一部分(例如侧边栏或页脚),特别是您只关心动态部分的控制器。这些解决方案足够灵活,可以满足大多数典型需求。
    有很多选项取决于您在该侧边栏中显示的内容 - 是静态的还是动态的?什么可以缓存?等等

    【讨论】:

    • 感谢您的回答,但我不清楚您发布的代码在哪个控制器中。据我了解,异步加载每个模型数据将允许我为每个数据拥有一个控制器,但如果我想要来自服务器的整个 HTML 怎么办?请忽略性能问题。 BeK 说我可以使用一个控制器来“处理它”,但这似乎很混乱(除非有一种我不知道的正确方法)。再次感谢。
    • 查看我编辑的答案。您通常每个视图都有一个控制器 - 即一个用于主页,一个用于 Contact 子页面,一个用于 News 子页面等...
    • 当然,在现实世界中,大多数情况下,您的页面(视图)不会整齐地映射到域模型。在视图中显示来自不同域模型或模型子集的数据对我来说听起来像是 ViewModel。 ViewModel 甚至可以由其他可重用的 ViewModel 组成。像描述的那样异步加载你的片段可能是有意义的,或者在你的控制器中构建一个更复杂的 ViewModel 可能更简单。像往常一样,这取决于...
    【解决方案2】:

    这里有几个选项。这实际上取决于您正在加载什么样的数据。如果其中一个数据请求需要很长时间,则在收集所有数据之前不会显示视图。如果您将视图分解为部分视图并让它们异步加载,用户将拥有更好的用户体验。通过这种方式,您可以拥有单独的控制器/控制器方法,符合 SRP 等模式。

    如果您希望所有数据都显示在每个页面的侧边栏中,那么处理它的控制器可能会是一个更简单的解决方案,但我还是建议您查看正在加载的数据,尤其是加载所有数据所需的时间。希望这能回答您的问题或让您走上正确的道路。

    【讨论】:

      【解决方案3】:

      遵循 SRP 的另一种方法是使用 MVC 子操作。

      创建许多模型和控制器。每个控制器负责自己的业务逻辑 例如。

      • PostsController
      • 新闻控制器
      • 游戏控制器
      • 家庭控制器

      从呈现 HomePage.cshtml 的 HomeController 开始

      <div>@Html.Partial("Login.cshtml", Model.CurrentUser)</div>
      <div>
          <hgroup>
              <h2>what's new</h2>
          </hgroup>
          <div>@Html.Action("WhatNew", "News")</div>
          <div>@Html.Action("RecentlyPosted", "Posts")</div>
      </div>
      <aside>
          <h2>Games</h2>
          <div>@Html.Action("MostPlayed", "Games")</div>
      </aside>
      

      您可以在 HomeController 中获取许多控制器/动作名称的列表作为字符串,然后在主页中呈现多个子动作。

      【讨论】:

        猜你喜欢
        • 2016-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-06
        相关资源
        最近更新 更多