【问题标题】:The form's view data is expected to be an instance of MyEntity but is an instance of ArrayCollection表单的视图数据应该是 MyEntity 的一个实例,但它是 ArrayCollection 的一个实例
【发布时间】:2016-12-01 09:43:29
【问题描述】:

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

控制器动作如下所示:

$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 或添加视图 转换类实例的转换器 Doctrine\Common\Collections\ArrayCollection 到一个实例 XxxBundle\Entity\Address.

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

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

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

【问题讨论】:

  • 一次购买可以有多个地址,对吗?如果是这样,请使用@DOZ 解决方案,但始终添加至少一个购买地址,以便显示地址表格。 $purchase->setAddress(新地址());
  • @Cerad 谢谢,这些信息也有帮助

标签: symfony doctrine-orm


【解决方案1】:

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

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

而不是这个:

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

通过这种方式,您可以将地址表单嵌入到采购表单中

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

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

你必须考虑对象。

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

因此,当您构建 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_add' =&gt; true

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

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

我希望它更清楚

【讨论】:

  • 感谢您的帮助,我已尝试使用 -&gt;add('addresses', CollectionType::class, array( 'entry_type' =&gt; AddressType::class)),但随后仅显示购买表单
  • 是的,您必须添加一些 javascript 来显示地址表单,请参见:symfony.com/doc/current/cookbook/form/…
  • 再次感谢,现在我明白了。我可能不得不重新考虑我的实体。我认为使用 javascript 在 DOM 中完成表单是一种不好的做法。就像它之前出现的那样,在我看来实际上更好,因为表单是完整的,没有 javascript。问题是我无法将数据刷新到数据库。我不认为用 javascript 解决这个问题的好习惯......?!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-03
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
相关资源
最近更新 更多