我正在开发一个有很多查询表格的项目 有许多字段“集合”将用于多个表单。 我想使用子表单,但是我还没有能够使用它。
我一直得到这个例外:
表单的视图数据应该是标量,数组或\ ArrayAccess实例的类型,但是是SiteBundle \ Entity \ EntityB类的实例。
You can avoid this error by setting the "data_class" option to "SiteBundle\Entity\EntityB"
或添加一个视图转换器,将SiteBundle \ Entity \ EntityB类的实例转换为标量,数组或\ ArrayAccess的实例。
我已将问题分离为一个比我的实际应用程序简单得多的示例,并在此处提供示例的源代码。示例是EntityB类的来源。
我的子表单中有一个选择字段,如果我将该字段注释掉,则异常消失,所以我猜它与此有关。
主要表格背后的实体:
// src/SiteBundle/Entity/EntityA.php
namespace SiteBundle\Entity;
class EntityA
{
private $customerCode;
private $customerName;
private $b; // (an instance of EntityB)
public function getCustomerCode()
{
return $this->customerCode;
}
public function setCustomerCode( $customerCode )
{
$this->customerCode = $customerCode;
return $this;
}
public function getCustomerName()
{
return $this->customerName;
}
public function setCustomerName( $customerName )
{
$this->customerName = $customerName;
return $this;
}
public function getB()
{
return $this->b;
}
public function setB( $b )
{
$this->b = $b;
return $this;
}
}
主要表格
// src/SiteBundle/Form/Type/FormA.php
namespace SiteBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FormA extends AbstractType
{
public function buildForm( FormBuilderInterface $builder, array $options )
{
$builder
->add( 'customerCode', 'text', [ 'label' => 'Customer code:', ] )
->add( 'customerName', 'text', [ 'label' => 'Customer name:' ] )
->add( 'b', 'FormB', [ 'label' => 'Option:' ] );
}
public function configureOptions( OptionsResolver $resolver )
{
$resolver->setDefaults( [ 'data_class' => 'SiteBundle\Entity\EntityA' ] );
} // configureOptions()
public function getName()
{
return 'FormA';
} // getName()
}
子表单背后的实体
// src/SiteBundle/Entity/entityB.php
namespace SiteBundle\Entity;
class EntityB
{
private $opt1 = false;
private $opt2 = false;
private $opt3 = false;
private $start;
private $end;
public function getOption()
{
return $this;
}
public function setOption( $val )
{
switch( $val )
{
case 1:
$this->opt1 = true;
$this->opt2 = false;
$this->opt3 = false;
break;
case 2:
$this->opt2 = true;
$this->opt1 = false;
$this->opt3 = false;
break;
case 3:
$this->opt3 = true;
$this->opt1 = false;
$this->opt2 = false;
break;
}
return $this;
}
public function getStart()
{
return $this->start;
}
public function setStart( $start )
{
$this->start = $start;
return $this;
}
public function getEnd()
{
return $this->end;
}
public function setEnd( \DateTime $end )
{
$this->end = $end;
return $this;
}
}
子表格
// src/SiteBundle/Form/Type/FormB.php
namespace SiteBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FormB extends AbstractType
{
public function buildForm( FormBuilderInterface $builder, array $options )
{
$builder
->add( 'option',
'choice',
[
'expanded' => true,
'multiple' => false,
'label' => 'Option:',
'choices' =>
[
'1' => 'One',
'2' => 'Two',
'3' => 'Three'
],
'attr' => [ 'class' => 'checkbox-inline' ],
] )
->add( 'start',
'date',
[
'label' => 'Start date:',
'widget' => 'single_text',
] )
->add( 'end',
'date',
[
'label' => 'End date:',
'widget' => 'single_text',
] );
}
public function ConfigureOptions( OptionsResolver $resolver )
{
$resolver->setDefaults( [ 'data_class' => 'SiteBundle\Entity\EntityB' ] );
}
public function getName()
{
return 'FormB';
}
}
services.yml中的条目
# src/SiteBundle/Resources/config/service.yml
form.a:
class: SiteBundle\Form\Type\FormA
tags:
- { name: form.type, alias: FormA }
form.b:
class: SiteBundle\Form\Type\FormB
tags:
- { name: form.type, alias: FormB }
控制器操作方法
/**
* @route( "/debug", name="debug" )
*/
public function debugAction( Request $request )
{
$b = new EntityB();
$b->setOption( 1 )
->setStart( new \DateTime( 'today' ))
->setEnd( new \DateTime( 'today + 7 days' ));
$a = new EntityA();
$a->setCustomerCode( '1234' )
->setCustomerName( 'Test Customer' )
->setB( $b );
$form = $this->createForm( 'FormA', $a );
$form->handleRequest( $request );
if( $form->isValid() )
{
$this->getFlashbag()->add( 'info', "Form successfully validated" );
}
$vars =
[
'form' => $form->createView()
];
return $this->render( 'SiteBundle:debug:form.html.twig', $vars );
} // debugAction()
我在EntityB::ConfigureOptions()
中设置了data_class参数,这使得上面的异常消息的突出显示部分更加混乱。
我怀疑我错过了一些相当基本的东西,但不知道是什么。
环境:
- PHP 5.5.9
- Symfony 2.7.3
我今天跑了composer self-update
和composer update
,以确保我是最新的。
答案 0 :(得分:0)
原来,@ Cerad的第一条评论是正确的。
formb期望实体b有一个名为option的属性。 EntityB :: getOption返回$ this,解释了错误。调整getOption以返回实际的缩放器值。
我不知道为什么我的初步测试失败了,但后来的测试成功了。
我必须说,例外的措辞是非常误导和混淆的。