【问题标题】:Need a light understanding MVC pattern需要简单了解 MVC 模式
【发布时间】:2011-09-03 21:51:43
【问题描述】:

您有以下网址: http:///www.site.com/controller/method/values/1/2/3

我是否必须始终调用控制器,或者我可以调用视图并在视图内或在引用此视图的引导文件中实例化控制器?

我不明白的是,如果我在视图上需要超过 1 个控制器,如何归档?

例如: 在我的索引页面上,我想运行一个简单的 CMS,管理员可以在其中更改站点的文本块和图像。那将在内容管理控制器上。 在我的索引页面上,我还获得了最新添加的产品 vitrine,这些产品将由控制器产品控制。 如果我定义 www.site.com/contentmanagement 或 www.site.com 来运行 contentmanagement 控制器,产品控制器将如何被调用?

另外,还有一个例子。在我的菜单上,我有一个指向名为 aboutus 的页面的链接,这将是一个简单的页面,唯一需要的功能是用于管理文本块的内容管理控制器。

如果我遵循我阅读所有地方的模式,我将以如下链接结束: http://www.site.com/contentmanagement/method/aboutus ?

有点迷路了,因为这个 URL 肯定看起来很奇怪。让 URL 调用视图 http://www.site.com/aboutus 和一个引导文件会容易得多,我可以在其中告诉控制器应该在冲浪者在那里时加载...

引导程序看起来像:

开关($视图) 案例:索引 控制器负载内容管理 控制器负载产品 案例:关于我们 控制器加载内容管理

感谢您提供的任何帮助或提示,谢谢。

顺便说一句,我用 PHP 编码。

【问题讨论】:

    标签: php oop model-view-controller design-patterns controller


    【解决方案1】:

    嗯,如果你想要网站的文本块和图像(一个控制器)和产品橱窗(第二个控制器),那么在一个控制器中调用你需要的方法..

    我会这样做:当您请求包含上面提到的所有元素的索引页面时,实际上会调用一个控制器,它决定要显示哪个视图.. 所以在那个控制器中,您调用所有方法需要,获取数据,并将其传递给视图..如果从其他控制器调用方法,只需调用该方法并获取数据..我经常在控制器中制作一些静态方法,我可以在任何地方调用它们,所以我不必实例化整个对象..

    例如你调用 www.site.com/contentmanagement,控制器被调用,它将显示索引视图,在那个控制器中,你调用你需要的所有方法,准备数据,并将该数据传递给将显示的最终视图。

    【讨论】:

    • 我正在尝试提供一种适用于我的业务的模式,这样我就可以在需求相同的情况下快速为客户的网站编写代码,而无需大量重写。那么,在我的控制器库上拥有一个内容管理控制器、产品控制器和其他控制器(如登录控制器、类别控制器)以及为每个项目编写一个特定的控制器是可行的吗?那么,在我的索引中,我会编写一个 index.controller 并在 index.controller 方法中调用其他的?现在,最好的解决方案是什么……继续……
    • 我的问题的第二部分?我想要一个像 site.com/about_us 这样的干净 URL,而不是像 site.com/main_controller/aboutus 这样的 URL ...有什么建议吗?如果我的第一个参数始终是视图/方法,那将是一种方法,默认情况下我加载一个名为 index.controller 的控制器,并且对于每个视图,我都有一个方法可以加载该视图所需的其他控制器,然后渲染风景?
    • 嗯,你不必这样做 site.com/main_controller/aboutus 是肯定的.. 每个站点都有两个方面,前端和后端,我完成了前端,所以它总是调用'默认情况下,内容模块,并显示内容..如果我有例如site.com/about-us,模块“内容”已加载(公共端),它检查 slug 'about-us' 并加载该内容.. 如果数据库没有 about-us slug,它会重定向到 404 页面,简单 :) 这是简化的过程..
    【解决方案2】:

    我必须始终调用控制器还是可以调用 (..blah blah..)?

    这有点取决于你对“call”的理解。

    控制器需要能够更改视图和模型的状态。 并且每个 View 都需要能够从 Model(s) 请求数据(在 Model2 MVC 中)。

    认为 Controller 不应导致 View 的渲染(这在所有 RoR 的奉承者中都很常见),就像 View 在 Controller 上执行操作时没有业务一样。

    我不明白的是,如果我在视图上需要超过 1 个控制器,如何归档?

    视图和控制器应该是 1:1 的关系。如果您的视图需要不止一个控制器,您可能需要研究 HMVC 架构。

    例如:在我的索引页面上,我想运行一个简单的 CMS,(.. more blah .. )如何调用产品控制器?

    CMS 应该是具有多个控制器的单独应用程序(或至少是模块)。

    如果我遵循我阅读所有地方的模式,我将以如下链接结束:http://www.site.com/contentmanagement/method/aboutus

    为什么不只是http://site.com/cms/content/2/edit(其中 2 是“关于我们”页面的 ID)。没有法律规定站点管理的 URL 结构必须反映公开可用的页面 .. 地狱 .. 它实际上会导致漏洞增加。

    【讨论】:

    • 谢谢,仍然很困惑,但会搜索更多这个主题。但我所说的 URL 是公共视图。 CMS 会从 CMS 数据库表中请求数据块,而产品会从 products 表中请求数据。
    • @Henrique 数据收集是由 DAO 完成的,包含在模型中。而且通常模型与 URL 没有直接关系。这实际上就是将模型放在首位的全部意义所在。
    • 我将有一个数据库模型,将从 CMS 控制器调用以处理内容管理,但也会从产品控制器调用以处理产品列表。
    • @Henrique 您还应该了解更多关于“域业务模型”、“域对象”和“数据映射器模式”的信息(不要误认为 ORM)。看来你对模型的理解有点偏差。
    • 这听起来可能很愚蠢,但是,我在上面的示例中称为控制器,cms,产品将是模型吗? index.controller 会将数据发送到 cms 模型,该模型将执行所有业务逻辑并将结果返回给 index.controller。产品也一样,然后 index.controller 会返回视图?
    【解决方案3】:

    我要试着走路

    我不明白的是,如果我在视图上需要超过 1 个控制器, 怎么存档?

    例如:在我的索引页面上,我想运行一个简单的 CMS,其中管理员 可以更改站点的文本块和图像。那将是 内容管理控制器。在我的索引页面上,我还得到了 最新添加的产品橱窗,什么将由 控制器产品。如果我定义 www.site.com/contentmanagement 或 www.site.com 运行内容管理控制器,产品如何 控制器会被调用吗?

    拥有包含控制器名称的 URL 肯定很好,但这不是 MVC 的要求。因此,您不必将控制器映射到 URL 本身。经典的 MVC 不会将自己绑定到特定的命名约定,因此您可以通过不同的 URL 调用您的产品控制器,然后处理产品并显示产品的视图。对于 MVC 而言,重要的是拥有一个控制器来处理模型并产生一个视图作为表示层。在您的特定示例中,您的入口点似乎是与 ContentManagement 和 Product Class/Module 交互的单个控制器,并且由此产生的交互产生单个视图。

    引导程序看起来像: 开关($视图) 案例:索引 控制器负载内容管理 控制器负载产品 案例:关于我们 控制器负载内容管理

    因此,您上面的原始交互并没有完全关闭,只是您并没有真正调用两个控制器,而是在点击索引时执行以下操作:

    • 加载一个控制器,我们称之为IndexController
    • 加载 ContentManagement 模块以获取相关内容,您可能希望将信息作为索引页面模型的一部分
    • 加载产品模块以获取相关产品,再次将其放入您的模型中
    • 将包含用于将页面呈现到视图中的信息的模型传递给视图
    • 在您的视图中,您呈现包含来自 ContentManagement 模块的内容和来自产品模块的产品列表的模型,从而生成单个视图

    如果我遵循模式,我会到处阅读,我将以 像这样的链接:http://www.site.com/contentmanagement/method/aboutus?

    这也不是必需的,您应该遵循对用户有意义且更容易的方法。此外,如果您需要遵守约定,您始终可以使用 URL 映射使您的 URL 更漂亮。

    【讨论】:

    • 谢谢,就像我刚刚添加的其他评论一样,可能会有 1 个控制器作为主控制器,始终加载,它将根据 URL 请求和我的编码方式决定加载哪些控制器它与 URL 请求进行交互。一直在考虑将 URL 的第一个参数作为方法获取,该方法获得相同的视图名称并在此方法中调用所有其他控制器。但是,我会以我网站的每页 1 个方法结束,这似乎有点程序性,不是吗?就像回到程序化编程。
    • 您不必构建方法切换。您仍然可以将一个 URL 映射到一个控制器/对象,并使用最后一个路径作为控制器的名称。因此,在您的示例中,简单的 site.com/aboutus 可以映射为在您的代码中加载 AboutUsController。我所说的 IndexController 是您的 www.site.com 自动映射到调用 ContentManagement 和 Product 模块的 IndexController。我并不是说作为基于方法的分支的单一入口点。还有你目前使用的是哪个 PHP 框架?如果我们理解这一点,可能有助于澄清。
    • 实际上我正在编写适合我需要的自己的框架。我所有的项目都基于同一个管理面板,所以它有点像 php+javascript+html 框架,一组集合,我可以在其中轻松构建客户的网站。孔目录的简单副本和过去以及一些调整我可以让相同的系统在不同的客户端上工作并编码他们的特殊要求。您假设是正确的, index 将映射到 indexController ,然后在其中我可以调用内容管理和产品模块。至于about us,它可以调用aboutus控制器和...
    • 它里面有规则来呈现内容管理或任何其他需要的模块......只是不想为每个页面名编写一个控制器,但它可能是要走的路吗?对吗?
    • 您的问题已经讨论了很长时间。有两种经典的 MVC 模式用于处理控制器。您提到的方法切换称为前端控制器模式,而每页控制器称为页面控制器模式。一些框架相互促进一种模式(例如 ASP.NET 更促进页面控制器模式,以便前端控制器)。最终,我觉得每个都有适当的用法,作为开发人员,您最终必须决定哪一个最适合您的情况。
    【解决方案4】:

    您要查找的内容称为HMVC,并且有几个框架可以解决这个问题,例如Kohana

    另请参阅此问题:

    What is the HMVC pattern?

    【讨论】:

      猜你喜欢
      • 2011-09-09
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-14
      • 2014-01-23
      • 1970-01-01
      相关资源
      最近更新 更多