我有一个包含集合的表单。所以我有:
/* 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..。
发布于 2013-09-19 01:42:44
要了解这里发生了什么,您必须首先了解数据映射。当你调用
$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 数据锁定是为了防止数据映射器覆盖您刚刚存储的默认数据。如果您传递"data“选项,则会自动完成此操作。
最后,您将构建表单。现在,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);发布于 2014-05-10 07:22:45
正如Bernhard指出的那样,侦听器是实现此目的的唯一方法,因为数据在子窗体中还不可用。我使用eventListener解决了类似的需求。下面是我的代码的一个简化版本,我希望它能对你有所帮助:
我的View实体有一个父表单,它有很多字段,以及其他表单的集合。其中一个子表单用于关联的实体ViewVersion,它实际上需要为动态实体加载另一个表单集合,该动态实体是与View关联的内容类型。此内容类型可以是许多不同类型的实体之一,例如文章、个人资料等。因此,我需要找出在View数据中设置了什么contentType,然后找到指向该捆绑包的动态路径,并包含该formType。
一旦你知道如何做,它实际上是很容易的!
class ViewType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// Basic Fields Here
// ...
// ->add('foo', 'text')
// ...
// Load a sub form type for an associated entity
->add('version', new ViewVersionType())
;
}
}
class ViewVersionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// Basic Fields Here
// ...
// ->add('foo', 'text')
// ...
;
// In order to load the correct associated entity's formType,
// I need to get the form data. But it doesn't exist yet.
// So I need to use an Event Listener
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
// Get the current form
$form = $event->getForm();
// Get the data for this form (in this case it's the sub form's entity)
// not the main form's entity
$viewVersion = $event->getData();
// Since the variables I need are in the parent entity, I have to fetch that
$view = $viewVersion->getView();
// Add the associated sub formType for the Content Type specified by this view
// create a dynamic path to the formType
$contentPath = $view->namespace_bundle.'\\Form\\Type\\'.$view->getContentType()->getBundle().'Type';
// Add this as a sub form type
$form->add('content', new $contentPath, array(
'label' => false
));
});
}
}就这样。我刚接触Symfony,所以在EventListener中做所有事情的想法对我来说都是陌生的(而且似乎不必要地复杂)。但我希望,一旦我更好地理解了这个框架,它看起来会更直观。如本例所示,使用事件侦听器并不复杂,只需将代码封装在该闭包中(或将其作为described in the docs放入它自己的单独函数中)。
我希望这对某些人有帮助!
发布于 2014-09-09 23:30:40
在提交或正在编辑时,可以在将FormBuilder转换为表单实例时访问数据。对于集合类型,您可以尝试这样做:
...
$form = $formBuilder->getForm();
...
if ($this->getRestMethod() == 'POST') {
$form->handleRequest($this->get('request'));
if ($form->isValid()) {
$formData = $form->getData();
foreach ($formData['photos'] as $key => $collectionRow) {
var_dump($collectionRow['photoname']);
var_dump($collectionRow['size']);
}
}
}https://stackoverflow.com/questions/18870866
复制相似问题