表单的视图数据应该是MyEntity的一个实例,但它是ArrayCollection的一个实例

时间:2016-07-27 11:41:32

标签: symfony doctrine-orm

我可以创建一个工作正常的表单,但在尝试将数据刷新到数据库时会出错:

控制器操作如下所示:

$purchase = new Purchase();
        $form = $this->createFormBuilder($purchase)
            ->add('addresses', AddressType::class)
            ->add('quantity', IntegerType::class)
            ->add('toBeDeliveredAt', DateType::class)
            ->add('comment', TextareaType::class)
            ->add('save', SubmitType::class, array('label' => 'Submit'))
            ->getForm();

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($purchase);
            $em->flush();
        }

类AddressType如下所示:

public function buildForm(FormBuilderInterface $builder, array $options)

{
    $builder
        ->add('title', TextType::class)
        ->add('firstname', TextType::class)
        ->add('lastname', TextType::class)
        ->add('street', TextType::class)
        ->add('city', TextType::class)
        ->add('zipcode', TextType::class)
        ->add('country', TextType::class)
        ->add('phone', TextType::class)
        ->add('email', EmailType::class);
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'XxxBundle\Entity\Address'
    ));
}

但是这给了我以下错误:

  

表单的视图数据应该是类的实例   XxxBundle \ Entity \ Address,但是是类的实例   学说\ COMMON \收藏\ ArrayCollection中。您可以避免此错误   通过设置" data_class" null的选项或添加视图的选项   转换类实例的转换器   Doctrine \ Common \ Collections \ ArrayCollection到一个实例   XxxBundle \实体\地址。

如果我将data_class选项设置为null,我得

  

警告:spl_object_hash()要求参数1为对象,给定字符串

如何添加一个视图转换器,将类ArrayCollection的实例转换为Address的实例?

1 个答案:

答案 0 :(得分:4)

Addresses是一个数组集合,因此您必须将其用作表单中的集合,如下所示:

$builder->add('addresses', CollectionType::class, array(
            'entry_type' => AddressType::class
        ));

而不是:

$builder->add('addresses', AddressType::class)

通过这种方式,您可以将地址表格嵌入购买表格

您可以查看有关嵌入表单here

的集合的文档

解释(抱歉我的英语不好):

你必须考虑对象。

在您的购买实体中,您有一个地址集合,因为购买对象可以有许多地址,也就是说要保留购买对象,您必须提供一组地址。

因此,当您构建Purshase表单时,Symfony需要一个用于地址输入的数组集合。这是我上面写的。有了这个,如果你想要添加一个新的Purchase对象,当你去查看表单时,要显示与地址相对应的字段,你必须在你的表单中这样做:

    <ul class="addresses">
            {# iterate over each existing address and render these fields #}
            {% for address in form.addresses %}
                <li>{{ form_row(address.title) }}</li>

                 //do this for all the others fields ...

            {% endfor %}
    </ul>

但是如果你想动态添加许多地址,你必须做两件事:

首先,您必须在表单构建器

中添加'allow_add' => true
$builder->add('addresses', CollectionType::class, array(
        'entry_type'   => AddressType::class,
        'allow_add'    => true,
    ));

其次,allow_add还以生成的html格式为您提供“原型”变量:这是Javascript进来的地方:) 要做到这一点,你必须编写一些Javascript,你可以看到一个很好的例子here

我希望它更清楚