我有一个使用通过第三方API检索的选项构建的预订表单,并且由于需要具有最新信息,因此无法缓存API的结果(至少不会很长时间)。
我遇到的问题是我注意到提交表单时Drupal正在重新调用我的_form函数,它再次触发API调用,我想阻止它尝试减少数量进行的API调用。
显然,如果验证失败,则需要重新绘制表单,并且需要再次进行API调用,但我想知道是否有办法在表单验证时阻止它执行此操作,以便我可以阻止它许多不必要的API调用。
感谢您的帮助。
答案 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编码器的意志更强。