Symfony Forms:CollectionType - 不要将 null 转换为空数组
Symfony Forms: CollectionType - Don't transform null to empty array
我们 API 使用 Symfony Forms 来验证请求数据。目前我们正面临 CollectionType
的问题,它将提供的值 null
转换为空数组 []
.
因为区分用户供应 null
或空数组对我来说很重要,所以我想禁用此行为。
我已经尝试将 'empty_data'
设置为 null
- 不幸的是没有成功。
我的字段配置如下:
$builder->add(
'subjects',
Type\CollectionType::class,
[
'entry_type' => Type\IntegerType::class,
'entry_options' => [
'label' => 'subjects',
'required' => true,
'empty_data' => null,
],
'required' => false,
'allow_add' => true,
'empty_data' => null,
]
);
表单的处理方式如下:
$data = $apiRequest->getData();
$form = $this->formFactory->create($formType, $data, ['csrf_protection' => false, 'allow_extra_fields' => true]);
$form->submit($data);
$formData = $form->getData();
当前行为是:
输入$data
=>{ 'subjects' => null }
输出$formData
=>{ 'subjects' => [] }
我想要的行为是:
输入$data
=>{ 'subjects' => null }
输出$formData
=>{ 'subjects' => null }
经过多次尝试,我终于找到了解决方案,方法是创建 From Type Extension in combination with a Data Transformer
通过创建此表单类型扩展,我能够扩展 CollectionType
FormType 的默认配置。这样我就可以设置自定义构建 ModelTransformer
来处理我想要的行为。
这是我的表单类型扩展:
class KeepNullFormTypeExtension extends AbstractTypeExtension
{
public static function getExtendedTypes(): iterable
{
return [CollectionType::class];
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->addModelTransformer(new KeepNullDataTransformer());
}
}
这个需要在您的 service.yml 中使用 'form.type_extension'
标签注册:
PrivateApiBundle\Form\Extensions\KeepNullFormTypeExtension:
class: PrivateApiBundle\Form\Extensions\KeepNullFormTypeExtension
tags: ['form.type_extension']
Please note that you still use the CollectionType
in your FormType and not the KeepNullFormTypeExtension
as Symfony takes care about the extending...
在 KeepNullFormTypeExtension
中,您可以看到我使用 addModelTransformer
设置了一个自定义模型转换器,名为 KeepNullDataTransformer
KeepNullDataTransformer
负责将输入 null
保持为输出值——它看起来像这样:
class KeepNullDataTransformer implements DataTransformerInterface
{
protected $initialInputValue = 'unset';
/**
* {@inheritdoc}
*/
public function transform($data)
{
$this->initialInputValue = $data;
return $data;
}
/**
* {@inheritdoc}
*/
public function reverseTransform($data)
{
return ($this->initialInputValue === null) ? null : $data;
}
}
就是这样 - 这样,null
类型的输入将保持为 null
。
可以在链接的 Symfony 文档中找到有关此的更多详细信息:
我们 API 使用 Symfony Forms 来验证请求数据。目前我们正面临 CollectionType
的问题,它将提供的值 null
转换为空数组 []
.
因为区分用户供应 null
或空数组对我来说很重要,所以我想禁用此行为。
我已经尝试将 'empty_data'
设置为 null
- 不幸的是没有成功。
我的字段配置如下:
$builder->add(
'subjects',
Type\CollectionType::class,
[
'entry_type' => Type\IntegerType::class,
'entry_options' => [
'label' => 'subjects',
'required' => true,
'empty_data' => null,
],
'required' => false,
'allow_add' => true,
'empty_data' => null,
]
);
表单的处理方式如下:
$data = $apiRequest->getData();
$form = $this->formFactory->create($formType, $data, ['csrf_protection' => false, 'allow_extra_fields' => true]);
$form->submit($data);
$formData = $form->getData();
当前行为是:
输入$data
=>{ 'subjects' => null }
输出$formData
=>{ 'subjects' => [] }
我想要的行为是:
输入$data
=>{ 'subjects' => null }
输出$formData
=>{ 'subjects' => null }
经过多次尝试,我终于找到了解决方案,方法是创建 From Type Extension in combination with a Data Transformer
通过创建此表单类型扩展,我能够扩展 CollectionType
FormType 的默认配置。这样我就可以设置自定义构建 ModelTransformer
来处理我想要的行为。
这是我的表单类型扩展:
class KeepNullFormTypeExtension extends AbstractTypeExtension
{
public static function getExtendedTypes(): iterable
{
return [CollectionType::class];
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->addModelTransformer(new KeepNullDataTransformer());
}
}
这个需要在您的 service.yml 中使用 'form.type_extension'
标签注册:
PrivateApiBundle\Form\Extensions\KeepNullFormTypeExtension:
class: PrivateApiBundle\Form\Extensions\KeepNullFormTypeExtension
tags: ['form.type_extension']
Please note that you still use the
CollectionType
in your FormType and not theKeepNullFormTypeExtension
as Symfony takes care about the extending...
在 KeepNullFormTypeExtension
中,您可以看到我使用 addModelTransformer
设置了一个自定义模型转换器,名为 KeepNullDataTransformer
KeepNullDataTransformer
负责将输入 null
保持为输出值——它看起来像这样:
class KeepNullDataTransformer implements DataTransformerInterface
{
protected $initialInputValue = 'unset';
/**
* {@inheritdoc}
*/
public function transform($data)
{
$this->initialInputValue = $data;
return $data;
}
/**
* {@inheritdoc}
*/
public function reverseTransform($data)
{
return ($this->initialInputValue === null) ? null : $data;
}
}
就是这样 - 这样,null
类型的输入将保持为 null
。
可以在链接的 Symfony 文档中找到有关此的更多详细信息: