Magento - 处理块中表单的最佳方法?

Ada*_*mos 7 forms model-view-controller controller block magento

我来自不同的MVC框架(例如Symfony)到Magento.我读了很多关于Magento最佳实践的内容,我可以看到Magento没有使用典型的MVC风格.Alan Storm写道如下:

控制器的责任不是为视图设置变量控制器的工作就是对模型执行某些操作,然后告诉系统它的布局渲染时间.

我想我理解这种方法,因为这可以为块提供一种灵活性.

对.但形式怎么样?

在典型的MVC框架中,您将获得控制器中的请求参数,验证控制器中的表单数据,进行模型操作(保存,加载等)或必要时重定向,当一切都干净整洁时,您将提供新鲜出炉的视图输出件.

在Magento中,这些都应该发生在一个块内,而(瘦)控制器只应该准备布局然后再渲染它.(如果我理解的话.)

我试图找到一篇文章(手册,论坛主题,任何内容),它描述了一个单独模块的创建步骤,该模块具有自己的新模型,可以通过用户在前端的表单进行编辑.我想看看自定义表单应该如何在前端工作.我发现只有关于块,表单,修改或创建adminhtml表单或自定义联系人或简报注册表单的一般文章.

我做到了.它现在有效,但我不满意.那么,我检查了核心模块中Contact表单的源代码,这些对我来说搞乱了整个图片.内置的Contact表单使用IndexController进行上述大多数操作,(几乎)就像标准的MVC一样.

任何人都可以向我建议一个最佳实践,如何管理如下的简单流程?(我在下面有这些解决方案,但我不确定,是"正确的Magento方式"):

  • 页面加载时,在块中显示一个表单,该表单包含在单独的页面中
  • 通过请求参数从DB加载模型对象
  • 将对象数据填充到表单中
  • 当用户提交表单时,处理表单数据,验证它们
  • 如果验证错误,请再次显示该表单,然后弹出错误消息
  • 如果确定,将数据存储到数据库中,显示一个感谢页面

我的困惑主要在于:

  • 我应该在哪里获取并管理请求参数?(我在块类文件中做过)
  • 并根据它从DB加载一个对象?(另外,然后传递给phtml)
  • 如果我不加载它,如何将它传递给视图?(我知道一种方法,但我不知道最好的方法.)
  • 应该在哪里处理,验证和存储(POST)表单数据?(块?)
  • 如何在块中正确使用重定向?我是否需要重定向,因为感谢页面应该是不同的块/页面?或者只是同一块的替代(条件)外观?

Sla*_*den 3

您只需查看 Customer/AccountController 并查看loginPost,createPost方法如何处理传入的表单数据。

我永远不会将CRUD逻辑添加到块中。您需要在控制器中验证和处理 POST 数据。块应该只包含与视图相关的逻辑:例如 format url 或prepare Collection

此外,表格准备工作也落在了控制员的肩上。您需要加载对象并在控制器操作中验证它。那么有几种方法可以将其传递给块:

  • Mage::register(登记处)
  • $this->getLayout->getBlock('your_form_block')->setEntity($object)(直接设置变量为block)

任何重定向都应仅在控制器中完成。

更新 关于为什么在控制器内加载模型的几句话。

  1. 如果您无法加载对象,则意味着用户使用的 url(带有对象 ID)已过时,并且您可能需要将客户重定向到某个出现错误的方便页面。
  2. 正如我上面所说,所有重定向都应该仅在控制器中完成。这是为什么?因为目前块是进程,Magento 已经完成了大量的引导工作 - 例如loadLayout创建所有块。您不想让用户等待那么长时间只是为了之后重定向他。
  3. 此外,将重定向放置在控制器之外的任何位置都会使应用程序不可维护。当然也有例外,但你应该非常清楚自己在做什么。

而且你还忘记了一个更有价值的部分。如果控制器内的验证失败,您需要使用用户发送的值填写表单。在 Zend_Form 中,这做得很好,但是使用 Magento 表单,您需要使用会话(就像在 AccountController 中所做的那样) - 将所有键值部分保存在会话中,然后在块中检查这些会话变量是否存在。同样,只有当您的 POST 验证失败并且您将用户重定向回您的表单时,您才应该执行此操作。在成功的情况下,清除连接到表单的会话变量。

作为一般性建议:如果您想遵循 Magento 风格,请少读论坛,多读核心代码。