我正在 Symfony 5.4 中使用 Symfony Form,我需要以下内容:
我有一个具有一些属性的 DTO。在我们的应用程序中,默认的 ButtonType 在 theme-twig (按钮周围具有特殊类的特殊容器)中有一些特殊处理。
现在我需要另一个自定义按钮类型来为这个新用户提供他自己的特殊主题处理。
我为此构建了以下代码:
自定义按钮类型类:
class FormAddButtonType extends AbstractType
{
public const BLOCK_PREFIX = 'formaddbutton';
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'attr' => [
'class' => 'button blue-button',
],
]);
}
public function getBlockPrefix(): string
{
return self::BLOCK_PREFIX;
}
public function getParent(): string
{
return ButtonType::class;
}
}
现在我在表单中添加两个按钮:
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('test_button_1', ButtonType::class, [
'label' => 'Test Button 1',
'attr' => [
'class' => 'button blue-button',
],
'row_attr' => ['class' => 'noborder'],
]);
$builder->add('test_button_2', FormButtonType::class, [
'label' => 'Test Button 2',
'attr' => [
'class' => 'button blue-button',
],
'row_attr' => ['class' => 'noborder'],
]);
}
第一个 Button 将毫无问题地渲染。但是第二个按钮(我的自定义按钮类型)会导致以下错误:
Can't get a way to read the property "test_button_2" in class "My\Name\Space\Dto\MyDataDto"
.
是的,这个类/对象没有名为“test_button_2”的属性。但“test_button_1”也不存在,并且该按钮工作正常。手动设置“'mapped'=> false”也不起作用。
如果我通过 POST_SET_DATA 侦听器将 FormAddButtonType 添加到自定义集合类型中,则没有问题。但如果我尝试在“主窗体”中使用它,它将无法工作。
你能告诉我我做错了什么吗?
添加
"mapped" => false
字段选项中,代表“该字段在实体中不存在”。
我认为它确实适用于默认的 ButtonType,因为他们可能将其设置在
$resolver->setDefaults([ /* ... */ ]);
方法
文档:https://symfony.com/doc/current/reference/forms/types/form.html#mapped
对于仍在寻找答案的人:
您的自定义表单类型需要实现
\Symfony\Component\Form\ButtonTypeInterface
或 \Symfony\Component\Form\SubmitButtonTypeInterface
。
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\ButtonTypeInterface;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class YourCustonButtonType extends AbstractType implements ButtonTypeInterface
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
//...
]);
}
public function buildView(FormView $view, FormInterface $form, array $options): void
{
//...
}
public function getParent(): string
{
return ButtonType::class;
}
public function getBlockPrefix(): string
{
return 'your_block_prefix';
}
}
表单构建器将在内部检查您的表单类型是否实现了上述接口之一,如果是,它将使用特殊的
ButtonBuilder
/ SubmitButtonBuilder
而不是通用的 FormBuilder
,它试图将您的字段映射到您所在的对象传递到表格