我可以从视图中调用模型吗? [英] Can I call a Model from a View?

查看:68
本文介绍了我可以从视图中调用模型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个最适合我的用途,而不是使用成熟的PHP MVC.我已经完成了基本框架,并编写了运行网站所需的模型和控制器.

Rather than use a full-blown PHP MVC, I'm designing one that will best-fit my uses. I have the basic framework done, and have coded the models and controllers I'll need to run my website.

现在,我进入视图",遇到了一个小难题.我的方法对我来说很好,但是为了将来参考,我想知道我在做什么是否有不好的习惯.

Now I'm moving onto the Views, and I've encountered a small dilemma. My approach is working fine for me, but for future reference, I want to know if what I'm doing is a bad habit to get into.

我要做什么:

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

In my View, I'm calling a Model that runs my authentication system, and requesting the login status of a user. I then use that boolean to decide whether to show certain elements within the view, and where to place others.

我应该为每个登录状态设计单独的视图,还是这种方法很好?但是,如果要在为客户执行的工作中实现此MVC,则需要使用最佳实践.

Should I be designing separate views for each login status, or is this approach fine? However, if I'm going to be implementing this MVC into the work I'm doing for my clients, I need to use the best practices.

任何建议将不胜感激!

推荐答案

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

Can I call the model from the View?

是的,您可以.只要您保持M,V和C之间的关注点分离,您就可以自由调用模型(或控制器) ).大多数MVC图至少显示了View和Model之间的双向连接.不过,您不想执行的操作是将来自模型(或控制器)的逻辑/代码放入视图中,而您不想从那里修改模型.

Yes, you can. As long as you maintain the separation of concerns between M,V and C, you are free to call upon the Model (or the Controller) from the View. Most MVC diagrams show a bidirectional connection at least between View and Model. What you don't want to do though, is place logic/code from the Model (or the controller) into the View and you don't want to modify the model from there.

例如,您的页面上可能有一个小部件,该小部件汇总了网站每个页面上您喜欢的博客中最新的十个博客文章标题.您可以通过调用模型中的MyFavFeeds::getLatest();来获得头条新闻.您现在有什么选择?

For example, you might have a widget on your page that aggregates the latest ten blog posts headlines from your favorite blogs on each page of your website. You get the headlines by calling, say MyFavFeeds::getLatest(); in your model. What are your options now?

  1. 可以添加代码以将标题获取到控制器中,但这将要求您在每个控制器操作中都复制它,这与DRY原理背道而驰.另外,控制器的关注点是处理特定操作的用户输入,并且获取每个呼叫的标题可能甚至与这些操作无关.
  2. 如果您的体系结构支持它,则可以通过某种preDispatch挂钩获取该数据,即,将标题从插件或回调中加载并注入到View中.那将是DRY,但是第二个开发人员可能不知道该插件,并意外地覆盖了保存其控制器操作标题的变量.在某些情况下,您可能不想加载标题,例如当仅呈现表单提交的确认页面时,那么您必须具有禁用该插件的机制.有很多考虑.
  3. 您可以将对MyFavFeeds::getLatest()的调用(而不是对MyFavFeeds::getLatest()的代码)放入视图"或布局"模板,或者更好的是,将ViewHelper封装到模型类的调用并呈现小部件.这样,您不必担心会覆盖任何变量或重复.而且,当您不需要视图上的标题时,只需不添加标题即可.
  1. You could add the code to fetch the headlines into the controller, but that would require you to replicate it in each and every controller action, which is against the DRY principle. Also, the controller's concern is handling user input for specific actions and fetching the headlines on each call is likely not even related to these actions.
  2. If your architecture supports it, you could fetch that data in some sort of preDispatch hook, that is, the headlines get loaded and injected into the View from a plugin or callback. That would be DRY, but a second developer might not be aware of that plugin and accidently overwrite the variable holding the headlines from his controller action. And there might be cases in which you wouldn't want to load the headlines, e.g. when just rendering confirmation pages for form submissions, so you'd have to have mechanism for disabling the plugin then. That's a lot to consider.
  3. You place the call to (not the code of) MyFavFeeds::getLatest() into the View or Layout template or, better, a ViewHelper, that encapsulates the call to your model class and renders the widget. This way you don't have to worry about overwriting any variables or repetition. And when you don't need the headlines on your view, you simply don't include it.

关于其他问题:

在我看来,我称其为 运行我的身份验证系统,并且 请求用户的登录状态. 然后我用那个布尔值来决定 是否显示某些元素 在视图内以及放置位置 其他人.

In my View, I'm calling a Model that runs my authentication system, and requesting the login status of a user. I then use that boolean to decide whether to show certain elements within the view, and where to place others.

身份验证是您希望在调用任何控制器操作之前在应用程序流程的早期执行的操作.因此,您不应在视图中运行(整个)身份验证系统.实际的身份验证不是与视图相关的逻辑.另一方面,只需要在身份验证后请求用户状态即可.例如,如果您要渲染一个显示用户名并提供登录/注销按钮的小部件,则可以执行类似

Authentication is something you will want to do early in the application flow, before any controller actions are called. Thus, you should not run your (entire) authentication system in the View. The actual authentication is not View-related logic. Just requesting the user status after authentication, on the other hand, is okay. For instance, if you want to render a widget showing the user name and giving a login/logout button, it would be fine to do something like

<?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;
    }
}

如果要由用户角色修改GUI的较大部分,则可能需要将View分为部分块并根据状态将其包括在内,而不是将所有HTML都写入View Helper.

If you got larger portions of your GUI to be modified by a User's role, you might want to break your View apart into partial blocks and include them based on the status, instead of writing all the HTML into a View Helper.

如果您只想基于用户角色呈现导航,请查看Zend Framework的Zend_NavigationZend_Acl,以了解他们的操作方式.

If you are only looking to render a navigation based on the user role, have a look at Zend Framework's Zend_Navigation and Zend_Acl to see how they do it.

这篇关于我可以从视图中调用模型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆