2010-10-06 119 views
7

我有一个预订表格,它是使用通过第三方API检索的选项构建的,并且由于需要获得最新信息,因此API的结果无法缓存(至少不会很长)。我可以在提交表单时停止Drupal重新创建表单吗?

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

显然,如果验证失败,它需要重新绘制表单,API调用将需要重新进行,但我想知道是否有办法阻止它做到这一点,当表单验证,所以我可以阻止它对API进行大量不必要的调用。

感谢您的任何帮助。

回答

3

您是否可以将API中的返回值存储在$ form_state ['storage']中,所以至少每次在再次调用API之前首先检查存储时调用_form。

+1

+1 - 我发布了一个更详细的答案,但这是解决问题的正确方法。 – 2010-10-07 07:21:04

0

第一件事,如果验证失败,Drupal有一个表单的副本,所以你的表单函数实际上不会被调用。

现在来解决。

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

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

4

如果表单要由Drupal处理,则无法避免重新创建表单。它是Drupals form processing workflow的中心部分:每个表格都是至少构建两次,一次用于初始输出,至少再次来自客户端的帖子进来。甚至可以不止于此,具体取决于什么该表格之后,例如在发生任何验证错误时重新显示(通常缓存版本在那时被使用,但取决于特定的表单)。

你应该做的就是按照西蒙斯的建议 - 在第一次调用到窗体设计器功能,让你的API调用,并将结果保存在$form_state['storage']['yourIdentifier'](“yourIdentifier”是不使用的标准表格处理一些字符串 - 通常先从你的模块名称)。在每次调用表单构建器函数时,都要检查结果是否已在$form_state['storage']之内。如果他们是,你只需使用这些,跳过API调用。

这样可以避免重复的API调用,并让您更好地控制如何/何时执行它们(例如,如果特殊情况需要从外部API进行重新访问,您还可以在验证期间清除这些结果)。

+0

感谢您的回应,我一直在努力做到这一点,但我有点麻烦。我在表单函数中设置$ form_state,但是当我提交表单时,它总是返回null。有没有任何例子可以解释如何更详细地工作?我查看了Drupal网站上的那些,但他们没有那么有用 – pogo 2010-10-08 08:19:23

+0

@pogo:如果没有看到表单构建函数,很难说出错,但常见的错误是使用错误的函数签名(http:///drupal.org/node/794694#comment-2949122)。也许你可以编辑你的问题来包含你迄今使用的代码? – 2010-10-11 09:31:23

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], 
     ); 
     } 
    } 
    } 
} 

这不清除表单第一次它的显示,因为$消息未设置,当你遇到验证他们仍然会出现错误。

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