symfony - 使用不同的属性多次调用 form_widget - Symfony & Twig
问题描述
我试图用不同的属性多次在我的表单中调用表单小部件。我收到错误消息-Field "x" has already been rendered, save the result of previous render call to a variable and output that instead.
我已经在所有可以修复的地方进行了修复,但是有些字段需要不同的属性。例如 :-
form_widget(foo.bar, {'value' : 'image'}) }}
和
form_widget(foo.bar, { 'attr': { 'class': 'hidden' }} )
是否有可能在同一个表单上调用具有不同参数的表单小部件?
解决方案
像你一样多次重用同一个小部件可能会产生奇怪的副作用,因为 Symfony 也会设置一个 html id,并且根据你放置字段的位置,你可能最终会得到无效的 html,这可能会导致你的 JavaScript 中断/执行奇怪的事情或提交表单。
确保您拥有有效 HTML(例如,没有重复的 id)的最安全方法是手动渲染每个元素,然后仅使用表单元素来获取当前内容/错误。为了做到这一点,您可以忽略form_widget
和form_row
帮助器,只需自己编写字段的 HTML,然后只插入您需要的部分,例如
<input name="{{ field_name(foo.bar) }}" type="file">
这个确切的例子需要 Symfony 5.2,因为field_name()
它是新的。见https://symfony.com/blog/new-in-symfony-5-2-form-field-helpers
不利的一面是,类似的东西{{ form_rest(form) }}
可能不再起作用,但至少你仍然可以使用任何只输出不是表单元素的表单部分的助手,例如form_error
,form_label
应该仍然可以工作,但form_widget
你form_row
应该避免。form_end
再次呈现所有剩余的字段,这就是为什么您可能也应该避免这种情况。Symfony 5.2 中引入的更具体的帮助器对于这种方法也非常方便。通过这种方式,您可以完全控制字段的呈现方式,并且可以更改您在多个位置使用的每个字段的类。
如果您使用旧版本的 Symfony,您可以通过查看提供它们的 TwigExtension并为您的应用程序调整它来自己实现辅助方法,例如提供您自己的具有类似功能的 AppTwigExtension。
如果你想继续使用form_widget
/form_row
那么你应该避免在同一个请求中多次渲染同一个表单(元素)。您可以尝试使用 sub-requres/ESI 之类的东西,但它可能会很麻烦。
有多种方法可以多次渲染表单,允许您每次都以不同的方式渲染它。例如,您可以创建一个 FormCollection,其中添加了两次相同的类型。然后你有一个包含 2 个表单的表单(你的表单两次)。您还可以为同一个表单创建多个实例,然后根据您使用的一个(foo 或 bar)在模板中以不同的方式呈现它们,例如类似的东西(只是粗略的轮廓,不确定这是否真的有效):
public function contact(Request $request): Response
{
$form1 = $this->createForm(FooFormType::class, null, ['attr' => ['id' => 'form1']]);
$form1->handleRequest($request);
if ($form1->isSubmitted() && $form1->isValid() {
// ...
}
$form2 = $this->createForm(FooFormType::class, null, ['attr' => ['id' => 'form1']]);
$form2->handleRequest($request);
if ($form2->isSubmitted() && $form2->isValid() {
// ...
}
// Do something
return $this->render('....html.twig', [
'foo' => $form1->createView(),
'bar' => $form2->createView(),
]);
}
如您所见,这有点多余,因此通常您希望避免这种方法,但是您应该在网上找到一些人们做类似事情的例子。
推荐阅读
- java - Java Lambda for break 在两个 for 循环中
- python - 如何基于一个公共列、研究站点“名称”组合 2 个熊猫数据框?
- html - 每行中具有相同提交按钮的表格:第一个提交按钮不起作用(多个相同的 id?)
- javascript - How to add two v-text-fields when I click a button dynamically using vuetify
- powershell - 当变量在引号中时,如何仍然获取文本文件的每一行?
- label - 如何在不同侧创建没有闭合间隔和闭合间隔的箱?
- sql - SQL 注入: or 1=1 vs ' or 1=1; -- -
- node.js - I get an error when build my Angular Application
- javascript - 在 PHP 中解码 JSON.stringify
- java - Extract data from DBpedia (connecting sparql endpoint from java)