删除来自空集合表单项的空值

Flo*_*ent 2 forms collections null symfony

我正在尝试在2个实体之间的形式中实现ManyToMany关系(例如,Product and Category to make simpe)并使用docs中描述的方法与原型和javascript(http://symfony.com/doc/current/ cookbook/form/form_collections.html).

以下是ProductType中创建类别集合的行:

$builder->add('categories', 'collection', array(
                   'type' => 'entity',
                   'options' => array(
                        'class' => 'AppBundle:Category',
                        'property'=>'name',
                        'empty_value' => 'Select a category',
                        'required' => false),
                   'allow_add' => true,
                   'allow_delete' => true,
              ));
Run Code Online (Sandbox Code Playgroud)

当我有一个新项目时,新的选择显示设置为空值"选择一个类别".问题是,如果我不更改空值,则将其发送到服务器,并在$ form-> bind()之后,我的Product对象在$ category ArrayCollection中获取一些空值.

我首先测试Product实体中setter中的值,并在ProductType中添加'by_reference'=> false,但在这种情况下,我得到一个异常,声明null不是Category的实例.

如何确保忽略空值?

Rom*_*ain 8

引用'delete_empty'上的文档:

如果要从表单中显式删除完全空的集合条目,则必须将此选项设置为true

$builder->add('categories', 'collection', array(
               'type' => 'entity',
               'options' => array(
                    'class' => 'AppBundle:Category',
                    'property'=>'name',
                    'empty_value' => 'Select a category'),
               'allow_add' => true,
               'allow_delete' => true,
               'delete_empty' => true
          ));
Run Code Online (Sandbox Code Playgroud)

由于您使用嵌入表单,因此可能会遇到一些问题,例如Warning: spl_object_hash() expects parameter 1 to be object, null given传递空集合时.

required=>false按照这个答案解释的删除对我不起作用.

类似的问题被引用这里在GitHub和解决由PR 9773


Flo*_*ent 7

我终于找到了一种方法来处理事件监听器.这个讨论给出了所有FormEvents的含义.在这种情况下,PRE_BIND(由2.1及更高版本中的PRE_SUBMIT替换)将允许我们在绑定到Entity之前修改数据.

查看Symfony源中Form的实现是我发现如何使用这些事件的唯一信息来源.对于PRE_BIND,我们看到表单数据将由事件数据更新,因此我们可以使用它来更改它$event->setData(...).以下代码段将遍历数据,取消设置所有空值并将其设置回来.

$builder->addEventListener(FormEvents::PRE_BIND, function(FormEvent $event){
    $data = $event->getData();
    if(isset($data["categories"])) {
        foreach($data as $key=>$value) {
            if(!isset($value) || $value == "")
                unset($data[$key]);
        }
        $event->setData($data);
});
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助别人!