13

我正在为过滤的实体集合显示一个 html 表,并且我想在每一行中显示一个复选框,作为表单的一部分,它将所选实体添加到会话 var。

我在想每个复选框都应该有实体 id 作为它的值,我会从表单字段数据中得到一个 id 数组(好的,所以值应该是实体的间接引用,但是为了简单)。

我尝试使用单个实体类型字段创建表单类型,映射到实体的 id 属性并嵌入到另一个具有集合类型字段的表单类型中。

class FooEntitySelectByIdentityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('foo_id', 'entity', array(
            'required'  => false,
            'class'    => 'MeMyBundle:FooEntity',
            'property' => 'id',
            'multiple' => true,
            'expanded' => true
        ));
    }

# ...

class FooEntitySelectionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('identity', 'collection', array(
            'type'   => new FooEntitySelectByIdentityType,
            'options'  => array(
                'required' => false,
                'multiple' => true,
                'expanded' => true,
                'attr'     => array('class' => 'foo')
            ),
        ));
    }

# ...

在控制器中,表单是使用实体集合作为初始数据创建的

$form = $this
    ->createForm(
        new \Me\MyBundle\Form\Type\FooEntitySelectionType,
        $collection_of_foo
    )
    ->createView()
;

呈现表单时,标识字段只有一个标签,但没有小部件。

甚至可以以这种特殊方式使用实体和集合类型字段吗?如果是这样,我可能做错了什么?

4

3 回答 3

8

我想这会回答你的问题。

忘记FooEntitySelectionType. 添加一个property_path字段选项FooEntitySelectByIdentityType并将data_class选项设置为null

class FooEntitySelectByIdentityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('foo_id', 'entity', array(
            'required'      => false,
            'class'         => 'MeMyBundle:FooEntity',
            'property'      => 'id',
            'property_path' => '[id]', # in square brackets!
            'multiple'      => true,
            'expanded'      => true
        ));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'      => null,
            'csrf_protection' => false
        ));
    }

# ...

并在您的控制器中,构建FooEntitySelectByIdentityType

$form = $this
    ->createForm(
        new \Me\MyBundle\Form\Type\FooEntitySelectByIdentityType,
        $collection_of_foo
    )
    ->createView()
;

然后在接收 POSTed 数据的控制器动作中:

$form = $this
    ->createForm(new \Me\MyBundle\Form\Type\FooEntitySelectByIdentityType)
;
$form->bind($request);
if ($form->isValid()) {
    $data = $form->getData();
    $ids  = array();
    foreach ($data['foo_id'] as $entity) {
        $ids[] = $entity->getId();
    }
    $request->getSession()->set('admin/foo_list/batch', $ids);
}

最后,在你的树枝模板中:

{# ... #}
{% for entity in foo_entity_collection %}
    {# ... #}

    {{ form_widget(form.foo_id[entity.id]) }}

    {# ... #}
于 2013-02-01T19:11:43.250 回答
3

如果有人正在寻找 Symfony >=2.3 的解决方案

你必须改变这个:

    $data = $form->getData();
    $ids  = array();
    foreach ($data['foo_id'] as $entity) {
        $ids[] = $entity->getId();
    }

对此:

    $data = $form['foo_id']->getData();
    $ids = array();
    foreach ($data as $entity) {
        $ids[] = $entity->getId();
    }
于 2014-04-12T09:23:23.917 回答
2

我创建了一个symfony 包,用于以可配置的方式将实体集合呈现为复选框表。虽然问这个问题已经有一段时间了,但我希望这可以帮助其他人解决同样的问题。

于 2016-04-18T14:00:29.460 回答