Symfony 表格';s视图数据应该是MyEntity的实例,但却是ArrayCollection的实例

Symfony 表格';s视图数据应该是MyEntity的实例,但却是ArrayCollection的实例,symfony,doctrine-orm,Symfony,Doctrine Orm,我可以创建一个工作正常但在尝试将数据刷新到数据库时出错的表单: 控制器操作如下所示: $purchase = new Purchase(); $form = $this->createFormBuilder($purchase) ->add('addresses', AddressType::class) ->add('quantity', IntegerType::class) ->

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

控制器操作如下所示:

$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();
        }
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'
    ));
}
类AddressType如下所示:

$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();
        }
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,但是类的实例 条令\公共\集合\阵列集合。您可以避免此错误 通过将“data_class”选项设置为null或添加视图 转换类实例的转换器 条令\Common\Collections\ArrayCollection到的实例 XxxBundle\Entity\Address

如果我将
data\u class
选项设置为null,我将得到

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


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

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

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

$builder->add('addresses', AddressType::class)
通过这种方式,您可以将地址表单嵌入到购买表单中

您可以看到关于嵌入表单集合的文档

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

你必须考虑对象

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

因此,当您构建Purshase表单时,Symfony需要一个数组集合来输入地址。这就是我上面写的。这样,如果您想要添加新的购买对象,当您查看表单时,要显示与地址对应的字段,您必须在表单中执行以下操作:

    <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\u add
还以html生成的形式为您提供了一个“原型”变量:这就是Javascript的作用:) 要做到这一点,您必须编写一些Javascript,您可以看到一个很好的示例


我希望它更清晰

谢谢你的帮助,我已经尝试了添加('addresses',CollectionType::class,array('entry\u type'=>AddressType::class))但是只有购买表单被显示是的,你必须添加一些javascript来显示地址表单,请看这个:再次感谢,现在我明白了。我可能需要重新思考我的实体。我认为使用JavaScript在DOM中完成表单是不好的做法。就像之前显示的那样,在我看来实际上更好,因为表单在没有javascript的情况下是完整的。问题是我无法将数据刷新到数据库中。我认为用javascript解决这个问题不是一个好的实践。。。?!一次购买可以有多个地址,对吗?如果是,则使用@DOZ解决方案,但始终至少添加一个购买地址,以便显示地址表单$采购->设置地址(新地址())@谢谢你,这些信息也很有帮助