我有一个包含一个集合的表单.所以我有:
/* my type */ public function buildForm(FormBuilderInterface $builder,array $options) { $builder ->add('name') ->add('photos','collection',array( 'type'=> new PhotoType(),'allow_add'=>true)); } /*Photo Type*/ public function buildForm(FormBuilderInterface $builder,array $options) { $builder ->add('photoname') ->add('size') }
但是我想访问照片中的数据,所以我在PhotoType里面试过:
$data = $builder->getData();
但似乎它不起作用,即使我正在编辑表单,所以照片集合有数据.
为什么我无法访问$builder-> getData()以另一个形式调用的形式?因为我试图不做和eventListener …
解决方法
要了解这里发生了什么,您必须先了解数据映射.你打电话时
$form->setData(array('photoname' => 'Foobar','size' => 500));
表单的数据映射器负责采用给定的数组(或对象)并将嵌套值写入表单的字段,即调用
$form->get('photoname')->setData('Foobar'); $form->get('size')->setData(500);
但在您的示例中,您不是处理Form,而是使用FormBuilder对象. FormBuilder负责收集表单的配置并使用此信息生成一个Form实例.因此,FormBuilder还允许您存储表单的默认数据.但是由于它只是一个简单的配置对象,所以它不会调用数据映射器.例如:
$builder = $factory->createBuilder() ->add('photoname') ->add('size') ->setData(array('photoname' => 'Foobar','size' => 500)); print_r($builder->get('photoname')->getData()); print_r($builder->get('size')->getData());
此示例将输出:
null null
因为数据映射发生在稍后,当我们将FormBuilder转换为Form实例时.我们可以使用这个事实为各个字段设置单独的默认值:
$builder->add('size',null,array('data' => 100)); // which is equivalent to $builder->get('size') ->setData(100) ->setDataLocked(true); print_r($builder->get('photoname')->getData()); print_r($builder->get('size')->getData());
输出:
null 100
需要数据锁定才能防止数据映射器覆盖刚才存储的默认数据.如果您传递“数据”选项,则会自动完成.
最后,你将建立表单.现在,FormBuilder在必要时调用Form :: setData(),这又会调用数据映射器:
$form = $builder->getForm(); // internally,the following methods are called: // 1) because of the default data configured for the "size" field $form->get('size')->setData(100); // 2) because of the default data configured for the main form $form->setData(array('photoname' => 'Foobar','size' => 500)); // 2a) as a result of data mapping $form->get('photoname')->setData('Foobar'); // 2b) as a result of data mapping (but ignored,because the data was locked) $form->get('size')->setData(500);