代码之家  ›  专栏  ›  技术社区  ›  BraedenP

我可以从视图中调用模型吗?

  •  6
  • BraedenP  · 技术社区  · 16 年前

    我设计的不是一个全面的PHP MVC,而是一个最适合我使用的。我已经完成了基本框架,并对运行我的网站所需的模型和控制器进行了编码。

    现在,我开始了解这些观点,我遇到了一个小的难题。我的方法对我来说很有效,但为了将来参考,我想知道我所做的是不是一个坏习惯。

    我想做的是:

    在我看来,我正在调用运行我的身份验证系统的模型,并请求用户的登录状态。然后,我使用这个布尔值来决定是否在视图中显示某些元素,以及在何处放置其他元素。

    我应该为每个登录状态设计单独的视图,还是这种方法可以?但是,如果我要在我为客户所做的工作中实现这个MVC,我需要使用最佳实践。

    任何建议都将不胜感激!

    4 回复  |  直到 16 年前
        1
  •  16
  •   Gordon Haim Evgi    16 年前

    我可以从视图中调用模型吗?

    是的,你可以。 只要你保持 关注点分离 在M、V和C之间,您可以从视图中自由调用模型(或控制器)。大多数MVC图至少显示了视图和模型之间的双向连接。但你不想做的是 逻辑/代码 从模型(或控制器)进入视图,您不想从视图修改模型。

    例如,您的页面上可能有一个小部件,它汇集了您网站每一页上最喜爱的博客的最新十篇博客标题。比如说,你通过打电话得到头条新闻 MyFavFeeds::getLatest(); 在你的模型中。你现在有什么选择?

    1. 能够 添加代码以将标题提取到控制器中,但这将要求您在每个控制器操作中复制它,这违背了dry原则。此外,管制员关心的是 处理特定操作的用户输入 每次电话上的头条新闻可能都与这些行为无关。
    2. 如果您的体系结构支持它,那么您可以在某种类型的predpatch钩子中获取数据,也就是说,从插件或回调加载标题并将其注入视图中。这可能很枯燥,但第二个开发人员可能不知道该插件,并且不小心覆盖了控制器操作中包含标题的变量。在某些情况下,您可能不想加载标题,例如,当只呈现表单提交的确认页面时,那么您就必须具有禁用插件的机制。这是很值得考虑的。
    3. 你打电话给(不是的代码) MyFavFeeds::getLatest() 在视图或布局模板中,或者更好的是,在视图帮助器中,封装对模型类的调用并呈现小部件。这样就不必担心覆盖任何变量或重复。当你不需要标题在你的观点,你只是不包括它。

    关于你的其他问题:

    在我看来,我正在召唤一个 运行我的身份验证系统,以及 请求用户的登录状态。 然后我用那个布尔值来决定 是否显示某些元素 在视图中,以及放置位置 其他。

    在调用任何控制器操作之前,身份验证是您在应用程序流早期要做的事情。因此,你不应该 运行(整个)身份验证系统 在视野中。实际的身份验证不是与视图相关的逻辑。另一方面,只需在身份验证后请求用户状态就可以了。例如,如果您想呈现一个显示用户名的小部件,并提供一个登录/注销按钮,那么可以执行如下操作

    <?php //UserHelper
    class UserMenuHelper
    {
        public function getUserMenu()
        {
            $link = '<a href="/user/logout">Logout</a>';
            if(MyAuth::userHasIdentity()) {
               $link = sprintf('<a href="/user/logout">Logout %s</a>',
                                MyAuth::getUsername());
            }
            return $link;
        }
    }
    

    如果用户角色要修改图形用户界面的较大部分,您可能希望将视图拆分为部分块,并根据状态将其包括在内,而不是将所有HTML写入视图帮助器。

    如果只希望基于用户角色呈现导航,请查看Zend框架的 Zend_Navigation Zend_Acl 看看他们是怎么做到的。

        2
  •  4
  •   jakecard    16 年前

    可以 但是你 不应该 . 除了一些极端情况(根据登录状态分支视图绝对不是“极端情况”)之外,从视图中调用模型资料几乎总是一个坏主意。

    在这种情况下,您可能希望通过控制器将布尔值传递给视图。这样,如果更改了用户模型的某些内容,那么只要控制器保持行为不变,视图就不必知道。

        3
  •  0
  •   moritz    16 年前

    好吧,我真的会尽量保持我的观点逻辑自由。如果需要根据模型方法的结果等切换任何内容,请放置一个代理渲染的控制器。

    只要确保你遵循基本的想法:在模型中做你的事情,告诉你的模型从你的控制器做什么,也告诉你的视图从你的控制器显示什么。

        4
  •  -1
  •   WedTM    16 年前

    虽然我对MVC的了解只够让自己陷入困境,但我一直坚持这样一个事实:除非您的视图是严格的用户界面,否则它不应该存在。

    此外,我还提出了瘦控制器、胖模型的概念。

    除此之外,我建议向您的身份验证系统模型添加一个方法,该方法返回要呈现的适当视图并将其传递给视图。

    推荐文章