我可以阻止Drupal在提交表单时重新创建表单吗?

时间:2010-10-06 15:21:10

标签: php drupal forms

我有一个使用通过第三方API检索的选项构建的预订表单,并且由于需要具有最新信息,因此无法缓存API的结果(至少不会很长时间)。

我遇到的问题是我注意到提交表单时Drupal正在重新调用我的_form函数,它再次触发API调用,我想阻止它尝试减少数量进行的API调用。

显然,如果验证失败,则需要重新绘制表单,并且需要再次进行API调用,但我想知道是否有办法在表单验证时阻止它执行此操作,以便我可以阻止它许多不必要的API调用。

感谢您的帮助。

4 个答案:

答案 0 :(得分:4)

如果要由Drupal处理表单,则无法避免重新创建表单。它是Drupals form processing workflow的核心部分:每个表单至少构建两次,一次用于初始输出,而至少再次从客户端发布进来。它甚至可以更多,取决于之后的形式,例如在发生任何验证错误时重新显示(通常当时使用缓存版本,但这取决于特定的表单)。

您应该遵循西蒙斯的建议 - 在第一次调用表单构建器函数时,进行API调用并将结果存储在$form_state['storage']['yourIdentifier']中('yourIdentifier'是标准表单处理未使用的字符串 - 通常以您的模块名称开头)。每次调用表单构建器功能时,都要检查结果是否已在$form_state['storage']中。如果是,您只需使用它们,跳过API调用。

这将避免重复的API调用,并使您可以更好地控制如何/何时执行它们(例如,如果特殊条件要求从外部API重新获取,您还可以在验证期间清除这些结果)。

答案 1 :(得分:3)

你可以在$ form_state ['storage']中存储/缓存来自API的返回值,所以至少每次在再次进行API调用之前先检查存储时都会调用_form。

答案 2 :(得分:0)

首先,如果验证失败,Drupal会有一份表单副本,因此实际上不会调用表单函数。

现在解决方案。

  • 您可以重定向到表单提交中的新页面,避免重新调用表单。
  • 不要直接在菜单定义中调用表单,而是调用表单调用。然后,您可以测试表单是否已提交,并且仅在需要时调用表单函数。

如果你担心API调用,你也可以将它缓存5-10分钟,这将使我的两个建议过时。

答案 3 :(得分:0)

Drupal不能这样做? “不能”不在我的词汇中!

我有同样的问题,但我不能让它击败我。以下是我克服它的方法:

在处理表单中,在我将详细信息插入数据库(或电子邮件或其他)后,我设置了2个像这样的drupal状态消息

function process_form($form){
  $success = do_email($form);
  if ($success){
    drupal_set_message("Success");
    drupal_set_message("Your form worked!");
  }
}

在表单生成器中,我读取并清除消息,清除表单并输出状态消息作为标记:

function form_generator($form_state,$parameters){
  $form = array();
   ...// This is where I make the regular form
  $messages = drupal_get_messages(); // this gets the messages and clears them
  if (isset($messages["status"])){
    if (isset($messages['status'][0]) && isset($messages['status'][1])){
      if ($messages['status'][0]=="Success"){
        $form = array(); // This clears the form I've just made
        $form['final_message']= array(
          '#type' => 'markup',
          '#markup' => $messages['status'][1],
        );
      }
    }
  }
}

这不会在第一次显示时清除表单,因为未设置$ messages,当您遇到验证错误时,它们仍然会出现。

Drupal魔术棒我们的方式,但PHP编码器的意志更强。