MVC逻辑:View需要更多数据

时间:2011-11-14 13:16:20

标签: model-view-controller

我是MVC的新手,我可能还没有完全理解它的逻辑,这就是为什么我总是遇到麻烦。

在我看来,MVC应该将Web应用程序的三个部分分开:模型(处理数据:获取,更改等),Controller(根据用户决定返回哪些数据作为响应)请求)和视图(将从控制器获取的数据(例如,转换为HTML)转换回用户作为响应)。

“分离”意味着这三个元素彼此抽象。 Controller不关心Model部分实现的细节(反之亦然),它只是告诉他需要获取(或改变)的数据并知道如何处理它,Model与之无关视图(即数据转换方式)。 最后,Controller与View转换无关,他只知道需要转换哪些数据(取决于请求)以及以何种方式(例如,为当前数据选择正确的模板)。 而View部分是从Controller中抽象出来的,它的工作是以某种预设的方式转换输入数据的特定数组。

现在让我们说我有一个网站。它有索引页面(/)和一些非索引页面(/ vacancy /,/ about /,/ articles / bytag / fun / 5 /等)。 每页顶部都有一个徽标。问题是:我希望徽标是我网站每个页面上索引页面的超链接,除了索引页面本身(因为我不希望我的页面包含自己的超链接)。 所以我想要“< img src ='logo.png'>”在索引页面和“< a href =”/“>< img src ='logo.png'>< / a>”在其他页面上。

当然,我不想重复自己并使用相同的徽标图像创建多个模板(header_index和header_nonindex)。所以,我需要做的是检查我是否在我的模板的某个位置(在View部分内)的索引页面上,并根据添加或不添加链接标记的结果。

在这里,我面临一个逻辑问题。我无法在视图中获得地址(因为逻辑上这部分与用户请求无关,它转换数据,从Controller收到)。 所以我需要我的Controller将特定数据(例如页面地址或类似“isIndex”的布尔值)发送到View。但View不能“需要”来自Controller的数据,View就是数据转换的方式。因此,如果转换本身需要任何特定变量,则将其添加到Controller将使View依赖于特定的Controller和Controller - 与特定View相关,这将破坏抽象和分离的整个概念。 因此,如果不破坏MVC逻辑,就没有办法做我需要的。

我错了哪一部分?

2 个答案:

答案 0 :(得分:0)

你是对的,MVC的3个组件需要分开,它们的目的是保持代码的清洁和分离。

但这并不意味着他们是独立的。这并不意味着您可以使用任何VIEW并将其与任何CONTROLLER结合使用并期望它能够正常工作。

如果能够提供更好的解决方案,您可以随时扭转模式。 在这种情况下,您应该使用全局变量,可能是静态变量,可以通过MVC的3个组件访问。

因此,当您在索引页面的控制器中时,告诉您在索引页面中的静态变量,并且对于所有其他控制器使其成为默认值(默认=您不在索引页面上)。然后你可以在任何视图中使用那个静态变量,而不是控制器。

答案 1 :(得分:0)

一个经典的难题,但并不是特别孤立于MVC。在OOP中,您希望增加类中的内聚力并减少类之间的耦合。 MVC将同样的原则提升到架构级别,每个组件负责其活动,但与其他两个组件的操作分开。这是理想的情况,但就像在OOP中一样,理想并不意味着绝对分离。它们共享一些数据 - 控制器访问实体模型,构建视图模型和解释输入(通常作为基于Web的MVC中的模型)。视图使用视图模型,在Web上,视图是输入的来源。该模型可能是最孤立的。

现实是,分离不是绝对的,而是连续的。与其他架构模式相比,您有更多或更少的分离。 MVC倾向于更多"更多"在这方面,架构模式的分离结束,但并非所有MVC实现,甚至这些框架内的应用程序实例都是相同的。俗话说,"你可以用任何语言编写Fortran,"这意味着,如果您愿意,您可以在任何程度上违反设计模式,甚至可以将其破坏为另一种模式。

这并不总是坏事。你必须要务实。毕竟,目标不是实现纯粹的架构实现。目标是完成应用程序的业务。在您的情况下,您有一些UI目标,要求视图可以访问有关哪个控制器呈现它的一些详细信息。 ASP.NET MVC通过ViewContext属性公开它,而ViewContext属性又公开了对Controller,RouteData和HttpContext的引用。

您可以选择使用这些来实现您的业务目标,代价是架构模式的某些损坏,也就是说,视图现在正在处理一些"输入"并直接根据这些值做出一些决定。或者,您也可以通过增加视图模型的复杂性来选择保持分离,或者通过从包含一些内务处理属性的基础模型派生,或者在MVC中使用ViewBag作为每个模型的扩展。目的。这增加了与Controller的耦合,因为它现在需要知道View需要这些管家属性才能正确呈现。同样,它是一个连续统一体 - 你增加耦合,而不是创建耦合,而它并不存在。

我已经放弃了创建纯MVC的想法。是的,我希望尽可能接近MVC框架的范例。使用框架比使用框架更容易。然而,当我有一个目标时,这会导致我违反关注点的分离(经过彻底的检查以确保我真的需要),我更有兴趣以可持续和可维护的方式做到这一点,而不是跳过建筑箍做一些框架不适合的事情,或者最好以框架没有预料到的方式完成。