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

car*_*mba 4 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();
        }
Run Code Online (Sandbox Code Playgroud)

类 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'
    ));
}
Run Code Online (Sandbox Code Playgroud)

但这给了我以下错误:

表单的视图数据应该是 XxxBundle\Entity\Address 类的一个实例,但它是 Doctrine\Common\Collections\ArrayCollection 类的一个实例。您可以通过将“data_class”选项设置为 null 或通过添加将类 Doctrine\Common\Collections\ArrayCollection 的实例转换为 XxxBundle\Entity\Address 的实例的视图转换器来避免此错误。

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

警告:spl_object_hash() 期望参数 1 是对象,给定的字符串

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

TOZ*_*TOZ 7

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

$builder->add('addresses', CollectionType::class, array(
            'entry_type' => AddressType::class
        ));
Run Code Online (Sandbox Code Playgroud)

而不是这个:

$builder->add('addresses', AddressType::class)
Run Code Online (Sandbox Code Playgroud)

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

您可以在此处查看有关嵌入表单集合的文档

解释(对不起,我的英语不好):

你必须考虑对象。

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

所以当你构建你的 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>
Run Code Online (Sandbox Code Playgroud)

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

首先,您必须'allow_add' => true在表单构建器中添加

$builder->add('addresses', CollectionType::class, array(
        'entry_type'   => AddressType::class,
        'allow_add'    => true,
    ));
Run Code Online (Sandbox Code Playgroud)

其次,allow_add它还以生成的 html 形式为您提供了一个“原型”变量:这是 Javascript 的用武之地:) 要做到这一点,您必须编写一些 Javascript,您可以在这里看到一个很好的例子

我希望它更清楚