Forms Symfony2:Form';s视图数据问题

Forms Symfony2:Form';s视图数据问题,forms,symfony,Forms,Symfony,大家好,我在使用Symfony2 FormBuilder时遇到了一些问题,事实上,我有一个实体用户(一个接一个)链接到一个实体地址,看起来很简单,但当我试图将AddressType表单嵌入UserType One时,我遇到了一个例外: 表单的视图数据应该是Acme\Bundle\AddressBundle\Entity\Adresse类的实例,但却是Doctrine\Common\Collections\ArrayCollection类的实例。您可以通过将“data\u class”选项设置为n

大家好,我在使用Symfony2 FormBuilder时遇到了一些问题,事实上,我有一个实体用户(一个接一个)链接到一个实体地址,看起来很简单,但当我试图将AddressType表单嵌入UserType One时,我遇到了一个例外:

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

我在这里放了一些代码(简化为可读),以使我的问题更容易理解:

我的用户类(扩展FosUserBundle类):

class User extends BaseUser
{
  ...

  /**
  * @ORM\OneToOne(targetEntity="Acme\bundle\AddressBundle\Entity\Address", cascade={"persist", "remove"})
  * @ORM\JoinColumn(nullable=true)
  * @Assert\Valid
  */
  public $address;

  .......

}
 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);

        // add your custom field
        $builder->add('name','text')
                ->add('address',new AddressType(),array(

                            'data_class' => 'Acme\Bundle\AddressBundle\Entity\Address'

                    )
                );


    }
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
       $builder->add('city','text')
                ->add('title','text');
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
             'data_class' => 'Acme\Bundle\AddressBundle\Entity\Address'
        ));
    }
链接表单类型buildForm函数:

class User extends BaseUser
{
  ...

  /**
  * @ORM\OneToOne(targetEntity="Acme\bundle\AddressBundle\Entity\Address", cascade={"persist", "remove"})
  * @ORM\JoinColumn(nullable=true)
  * @Assert\Valid
  */
  public $address;

  .......

}
 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);

        // add your custom field
        $builder->add('name','text')
                ->add('address',new AddressType(),array(

                            'data_class' => 'Acme\Bundle\AddressBundle\Entity\Address'

                    )
                );


    }
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
       $builder->add('city','text')
                ->add('title','text');
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
             'data_class' => 'Acme\Bundle\AddressBundle\Entity\Address'
        ));
    }
我的地址表单类型:

class User extends BaseUser
{
  ...

  /**
  * @ORM\OneToOne(targetEntity="Acme\bundle\AddressBundle\Entity\Address", cascade={"persist", "remove"})
  * @ORM\JoinColumn(nullable=true)
  * @Assert\Valid
  */
  public $address;

  .......

}
 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);

        // add your custom field
        $builder->add('name','text')
                ->add('address',new AddressType(),array(

                            'data_class' => 'Acme\Bundle\AddressBundle\Entity\Address'

                    )
                );


    }
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
       $builder->add('city','text')
                ->add('title','text');
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
             'data_class' => 'Acme\Bundle\AddressBundle\Entity\Address'
        ));
    }

提前感谢您的帮助

您的地址是一个实体,因此您需要让表单知道字段类型是从实体加载的。请看这里:

试着这样做:

$builder->add('name', 'text')
        ->add('address', 'entity',array(
              'class' => 'AddressBundle:Address',
              'property' => 'address'
));

一个问题是,您将地址设置为公共财产。在原则2中,你需要使你的财产私有或受保护。D2依赖于此实现延迟加载。基本上,你的地址永远不会被加载,尽管为什么你会得到一个数组是一个谜。您是否正在将地址初始化为构造函数中的数组?可能是复制/粘贴错误

你应该:

class User extends BaseUser
{
    protected $address;

    public function getAddress() { return $this->address; }
您还需要确保UserObject始终有一个Address对象,否则表单会抱怨

========================================================

看着你的垃圾桶,我看到:

class User extends BaseUser
{
public function __construct()
{
    $this->adresse = new \Doctrine\Common\Collections\ArrayCollection();
}
这不仅解释了不需要的数组,还将搞乱fos用户基类,因为它的构造函数没有被调用

我建议您将表单类型减少到最小的用户/地址,并使其正常工作。然后加入你的绒毛和其他东西。事实上,只需从创建一个简单的用户开始,然后添加地址


您没有展示如何创建用户对象,但请记住,在表单启动之前,由您来确保存在一个adress对象。条令不会为您创建它。

您尝试过错误消息中建议的内容吗?是的,我尝试过,但当我尝试时,我收到以下消息:spl\u object\u hash()期望参数1为object,字符串givenAn实体类型在您需要从现有实体列表中选择时使用。不完全是op想要做的。嗨,Cerad,谢谢,我已经从public更改为protected,我没有在构造函数中将Address初始化为数组,用户总是有一个Address对象链接到您的错误消息has…Entity\Address。。。但您的实体称为地址。复制粘贴问题?是否确实要将用户实体传递给表单?这几乎就像你的系统上有两个版本的用户。Cerad,这是一个复制粘贴问题,考虑AdRESSE作为地址,我正在使用FooSurBand及其注册窗体类型,唯一使用的用户实体是FoSuffBand扩展的一个(ACME /捆绑/用户捆绑/用户),你还有其他的表单类型吗?您是否有可能意外地在另一种表单类型中使用了data_class=>“Address”?考虑使用PaStBin来显示完整的类。我怀疑你在什么地方犯了一个简单的错误。您还可以在builder->add中传递数据类,这是不必要的。是的,我有一个其他表单类型,您可以在这里找到完整的代码:谢谢!