gre*_*emo 15 php symfony-forms symfony doctrine-orm symfony-2.3
[ 关于收集的文档 ]当嵌入表单(集合类型)可以为每个项目指定验证组时,基于当前项目?它似乎不适用于ATM.
的TaskType形式添加的标签的集合:
// src/Acme/TaskBundle/Form/Type/TaskType.php
// ...
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
$builder->add('tags', 'collection', array(
// ...
'by_reference' => false,
));
}
Run Code Online (Sandbox Code Playgroud)
例如,我们有两个标签(标签1和标签2),并使用"添加"按钮(通过JavaScript)添加新标签:
-----------
| add tag |
-----------
- tag 1 (existing)
- tag 2 (added clicking the "add tag" button)
Run Code Online (Sandbox Code Playgroud)
标签1应该针对组进行验证Default,Edit而标签2 Default仅针对组进行验证.
TagType 定义动态验证组的表单根据基础数据,如果tag是new,则获取Defaultgroup(如果存在Default)Creategroup:
// ...
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => function (FormInterface $form) {
$tag = $form->getData();
$groups = array('Default');
if (null !== $tag && null !== $tag->getId()) {
$groups[] = 'Edit';
}
return $groups;
}
));
}
// ...
Run Code Online (Sandbox Code Playgroud)
Tag "编辑"组中具有约束的实体Tag定义两个属性的示例(省略了访问器):
class Tag
{
/**
* @Assert\NotBlank()
*/
protected $name;
/**
* @Assert\NotBlank(groups={"Edit"})
* @Assert\Length(max="255")
*/
protected $description;
// ...
}
Run Code Online (Sandbox Code Playgroud)
对于现有标记:描述不应为空.对于新标签:说明可以为空白.
只需编辑现有标记并将描述留空即可.该表单验证,但验证服务显示错误:
$form = $this->createForm('task', $task)
->handleRequest($request);
$validator = $this->get('validator');
if ($form->isValid()) {
foreach ($task->getTags() as $tag) {
// Validate against Default, Edit groups
$errors = $validator->validate($tag, array('Default', 'Edit'));
if (null !== $tag && null !== $tag->getId()) {
echo 'Existing tag #'.$tag->getId();
} else {
echo 'New tag';
}
echo ', errors: '.count($errors).'<br>';
}
die('Form is valid.')
// ...
}
Run Code Online (Sandbox Code Playgroud)
输出:
Existing tag #863, errors: 1
Form is valid.
Run Code Online (Sandbox Code Playgroud)
更新1:我试过(没有成功),用静态方法determineValidationGroups的建议在这里:
public static function determineValidationGroups(FormInterface $form)
{
$groups = array('Default');
if ($form->getData() !== null && null !== $form->getData()->getId())
{
$groups = array('Edit');
}
var_dump($groups);
return $groups;
}
Run Code Online (Sandbox Code Playgroud)
在TagType形式:
/**
* {@inheritdoc}
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
// ...
'validation_groups' => array(
'Acme\TaskBundle\Entity\Tag',
'determineValidationGroups'
),
));
}
Run Code Online (Sandbox Code Playgroud)
使用一个现有标签输出和使用"添加标签"链接创建的标签似乎是正确的.但是现有标记没有错误,使描述留空:
array (size=1)
0 => string 'Edit' (length=4)
array (size=1)
0 => string 'Edit' (length=4)
rray (size=1)
0 => string 'Default' (length=7)
rray (size=1)
0 => string 'Default' (length=7)
Run Code Online (Sandbox Code Playgroud)
jil*_*lro 12
我用来测试我的答案的完整代码在https://github.com/guilro/SymfonyTests/tree/SO21276662上.
Valid 约束力验证器验证嵌入对象,而AFAIK API无法设置验证组.
但是在更高级别,我们可以要求Form组件将ValidationListener级联到所有嵌入表单,并使用Form组件API来设置验证组.
我们必须使用:
'cascade_validation' => true各个级别的FormBuilder中的选项.它false默认设置为.'error_bubbling' => false,默认情况下在集合中是真的 我们完成后,我们可以在相应字段旁边显示包含所有错误的表单.
在TaskType.php中:
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('tags', 'collection', array(
'type' => 'tag',
'error_bubbling' => false,
'allow_add' => true,
'by_reference' => false,
'cascade_validation' => true
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\TaskBundle\Entity\Task',
'cascade_validation' => true
));
}
}
Run Code Online (Sandbox Code Playgroud)
在TagType.php中:
class TagType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('description', 'text', array('required' => false));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\TaskBundle\Entity\Tag',
'validation_groups' => function(FormInterface $form) {
if ($form->getData() !== null && null !== $form->getData()->getId())
{
return array('Edit');
}
return array('Default');
},
'error_bubbling' => false,
));
}
}
Run Code Online (Sandbox Code Playgroud)