【问题标题】:php mvc form posts with alert on submit pagephp mvc 表单帖子在提交页面上带有警报
【发布时间】:2012-11-21 21:51:45
【问题描述】:

我在自己编写的 MVC 框架中遇到了一点问题。 当我将表单发布到另一个页面时,我想在那里显示警报。

例如:我在我的 mvc 框架中构建了一个博客。 这里有 3 个控制器/方法:'blog/overview'、'blog/addPost'、'blog/deletePost'。 当我在“博客/addPost”方法中时,它会使用如下形式调用视图:

<form action="blog/overview/" method="post">
  <input type="text" name="title" />
  <input type="text" name="post" />
  <input type="submit" name="addPost" />
</form>

如您所见,我将发布到方法“博客/概述”。 当表单发布并成功添加博客时,我希望能够显示一条警报,显示“博客文章已成功添加”。在“博客/概览”视图中。

这是否意味着如果有帖子,我必须检查方法“博客/概述”,以及它来自哪里?因为我想在删除博客文章时做同样的事情。这意味着我必须检查“博客/概述”中已经存在的两件事。在我看来,这不是正确的做法。

有人可以告诉我这是怎么做到的吗?

【问题讨论】:

  • 我也构建了一个表单验证器,但似乎我必须在“博客/概述”方法中做所有事情。只是为了在那里显示警报。我真的不认为这是正确的做法。

标签: php forms model-view-controller post alert


【解决方案1】:

任何(正确的)表单提交都遵循Post/Redirect/Get 模式,将其分为两个主要部分(阶段),必须应用于更大的 MVC 设计模式:

  • 第一阶段:POST-REDIRECT

    表格应使用&lt;form action="/blog/addPost" method="post"&gt; 发布。这将调用控制器中的addPost() 方法,该方法将必要的信息传递给模型层中的服务,该服务负责管理文章。

    所述服务尝试将您的文章保存在您使用的任何形式的永久存储中。如果此操作失败,服务会保存错误状态(通常在会话中)。如果操作成功,服务会将“最后一次操作”存储在会话中的某个位置,以便稍后恢复。

    然后查看,发现模型层发生了新变化,并通过生成响应重定向到 /blog/overview,其中仅包含 HTTP 位置标头。

  • 第二阶段:GET

    Controllers overview 方法被调用,但只是出于礼貌。

    当视图接收到一个产生响应的命令时,它首先请求模型层(很可能是管理文章库的同一个服务),是否有错误状态集。

    服务尝试从会话中恢复错误状态,如果之前存储过,则返回以查看错误代码。

    View 组装概览的 HTML 响应,如果模型层返回错误代码,则用于创建所述 HTML 的模板之一包含用于显示错误消息的片段。

    如果没有错误,视图可以请求模型层进行最后一次更改或最后一次操作,在成功发布后,您也可以将其存储在会话中。 这样视图会知道之前有一些操作完成,并且它还必须为“成功添加/删除”消息添加模板。

这将是简化的分步过程。您必须了解 MVC 和受 MVC 启发的模式是为在复杂的应用程序中提供结构而设计的,而您的博客可能过于简单,因此选择 MVC 设计模式可能不像您想象的那样务实。

【讨论】:

  • 因此,如果我是正确的:我会将表单发布到“blog/postAdd”,这确实会调用将帖子添加到数据库并向控制器返回响应的模型。此响应存储在会话中,成功添加后,我将重定向到“博客/概述”视图并阅读会话以获取警报?
  • 在正确实现的 MVC 中,控制器实际上从不从模型层检索信息。这是由视图实例(负责 UI 逻辑的类/对象)完成的。您可以说控制器“写入”到模型层并从中“读取”视图。模型层(通常由服务、领域对象和存储抽象组成,如数据映射器)在内部保存状态。然后视图的任务是生成overview,它从模型层请求有关该状态的信息。
  • 我的意思是控制器检查提交的数据是否有效,调用模型层将帖子添加到数据库。模型返回真或假。如果这是真的,则该帖子已成功添加。然后会在会话中添加一个警报,页面将重定向到“博客/概述”。在这里我必须检查会话中是否设置了警报?这是正确的做法吗?
  • 实际上数据的验证应该在domain objects(人们通常所说的“模型”的意思)中进行,它们是模型层的一部分。服务(来自模型层)不应向控制器返回任何内容。 View 应该直接请求之前的操作是否成功。
  • 我真的迷路了。你能告诉我例子/教程来解决我的问题吗?有没有像 Ian Overton 所说的那样在调度程序/路由器中执行此操作的解决方案?
【解决方案2】:

我总是检查哪个按钮被按下了

   if(isset($_POST['addPost'])){
    //do something
    header("Location: /blog/overview/");
   }

它的作用是,如果按下 addPost 提交按钮,它只会运行 if 语句中的代码。这样,如果表单上有两个按钮,则可以根据按下的按钮运行不同的代码。我希望这有助于/回答您的问题。

【讨论】:

  • 我知道这是检查表单是否已发布的代码。但是我是否检查了“博客/概述”方法中的每个表单帖子?
  • 是的。但是,如果您正在构建一个框架,如果您标准化您的词汇表,那么让路由器/调度程序卸载一些重复的控制器职责可能是有意义的。
  • 我在我的框架中使用了路由器/调度程序,但我不明白这将如何解决我的问题?
  • 调度程序可以检查常见的表单提交并在路由之前执行操作。例如,如果您正在执行 crud(创建、读取、更新、删除)操作,但使用不同的对象。它不需要作为重复代码存在于控制器中。在我处理这个问题的框架中,我实际上让处理渲染视图/布局的类处理了 crud 控制器操作,所以在 blog/overview 方法中,我只需要调用该方法来渲染页面并传入模型和它知道如何进行 crud 操作和渲染页面。
  • 这听起来像是解决我的问题的正确方法。你能告诉我一个例子/教程是如何做到的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
  • 2013-11-07
  • 2015-11-16
  • 1970-01-01
  • 2020-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多