真实世界MVC - 处理表格

时间:2009-09-16 13:14:36

标签: model-view-controller language-agnostic design-patterns

我仍然对MVC应该如何运作感到困惑。

假设我有一个销售小部件的网站。我有一个列表页面/widgets/list和一个产品页面/widgets/product/123

这两个都可以使用widget控制器并调用listproduct方法 - 到目前为止很简单。可以说我还有其他几个控制器用于各种事情。

现在我在我的标题中添加一个简报注册框 - 即在网站的每个页面上。 这怎么样?我认为它应该提交给/newsletter/signup

但是如果出现错误会发生什么(比如你没有正确填写你的电子邮件地址)?它应显示您所在的任何页面(例如/widgets/list),但newsletter控制器需要运行。 widget控制器不知道newsletter控制器,所以我不能把代码放在那里......这应该如何工作?

编辑:请不要AJAX - 我可以更容易理解。当javascript被禁用时,请考虑这是后备。

编辑2:非常感谢任何涵盖此类事情的示例或教程

编辑3:视图是否允许调用操作?例如,标题可能会调用Newsletter->index()

8 个答案:

答案 0 :(得分:6)

我不明白为什么每个页面上的简报框的错误消息都必须在同一页面中呈现。如果您有一个页面发布到另一个操作 - 与当前视图完全无关(例如 - 搜索),则没有理由在原始页面中显示错误消息。你会在同一页面上显示成功消息吗?那会在哪里处理?

新闻稿表单的错误消息应显示在专用于简报的视图中。例如,看看它在Stackoverflow中是如何完成的 - 进入搜索框并输入任何内容,只需按Enter即可。这是一种错误,因为您没有指定要搜索的内容。然后,Stackoverflow将带您进入另一个解释搜索工作方式的页面。

现在为什么这样做?原因很简单 - 用户在某个页面上并选择参与与当前页面无关的活动,因此没有理由将它们保留在那里。

答案 1 :(得分:1)

在新闻稿表单中添加一个字段,用于存储当前页面的URL。 在提交简报期间发生错误时,请检索URL并重定向到该页面。如果您将错误信息放在正确的位置,则应该通过新闻稿表单来获取,您可以将其包含在每个页面中。

答案 2 :(得分:1)

有一个很好的ASP.net MVC中心tutorial描述了在MVC环境中包含小部件(可重用组件)的方法。

基本思想是使用自己的请求管道设置小部件 - 不要将它们合并到一个组合的控制器/视图中,这会破坏MVC的可维护性。

答案 3 :(得分:0)

您必须将错误消息放在页面控制器(包括“子控制器”newsletter)可以接收的全局位置。

如果是AJAX,您可以让newsletter控制器与DIV对话,其中可见(因为您没有重新加载整个页面)。为此,您需要在AJAX请求完成时调用的页面中有一段JavaScript,它接受字符串并将其放在您想要的位置。

答案 4 :(得分:0)

我的MVC体验更实用,更少“书中所说的内容”,但这里有:

你有一个基本控制器类(在CakePHP中 - 这是我最熟悉的 - 它被称为AppController),它被所有其他控制器子类化。这个课程将实现你所谈论的所有“全球”内容。

实际例子:

在我的AppController类中,框架定义了一个beforeFilter()回调,它基本上在每个页面加载时执行。这是我检查注册表单是否已提交并正确处理的地方。如果注册以某种方式取消了,我会在会话中添加一些内容,并且我的视图只会检查是否存在源自新闻稿模型的错误列表,如果它们在那里,则显示它们。 / p>

在理论上这可能比你要求的更重一些,但是我没有接受任何这种废话的正式训练,所以我最好:)

答案 5 :(得分:0)

对于应该返回一些验证错误等的小部件 - 使用partial requests(或来自MvcContrib的子控制器)+ AJAX。

答案 6 :(得分:0)

我所做的是将每张表格贴到自己身上。在控制器中,我检查是否设置了post变量;如果是的话,我会做验证。如果验证成功,我会重定向到另一个页面。如果失败,表单页面将重新加载错误消息。这使得它变得简单并减少了代码重复。见这里:

**in controller**:

If post variable is set:
    validate form

    if form is validated:
        redirect to new page (or whatever)
    else:
        add error messages to the $data variable of the view
    endif

endif

//$data contains whatever information you'd normally pass to the view.
//if there was a validation error, the messages are added to the $data variable
show view with $data variable

如您所见,流程总是落到单个视图加载语句中。但是,如果验证成功,您将被带到另一页。

答案 7 :(得分:0)

如何向提交到/ newsletter / signup控制器的页面添加一个隐藏字段,其中包含控制器完成后的目标网址,即当前页面(或者您可以使用referer http标头)。

然后,此控制器将一个错误消息列表或成功消息添加到视图呈现的对象列表中,然后转发到上面隐藏字段指定的控制器。然后,该控制器将添加要在视图中显示的对象列表(例如,小部件列表)。

然后在视图中,您可以显示来自新闻稿控制器的错误消息(如果存在)。