【发布时间】:2013-10-30 19:18:28
【问题描述】:
在我的应用程序中,用户可以为某些实体创建自定义字段,然后在我显示表单时为每个实体对象设置此自定义字段的值。
实现是这样的:
1º) 我为表单创建了一个接口,我想要实现这个接口的表单。
2º) 我为所有表单创建了一个表单扩展:
app_core_form_builder.form_extension:
class: App\Core\Bundle\FormBuilderBundle\Form\FormExtension
arguments: ["@service_container", "@doctrine.orm.entity_manager"]
tags:
- { name: form.type_extension, alias: form }
3º) 在这个扩展中,如果表单实现了步骤 1 中引用的接口,我添加一个 EventSubscriber:
if($formType instanceof \App\Core\Bundle\FormBuilderBundle\Model\IAllowCustomFieldsdInterface){
$builder->addEventSubscriber(new FormSubscriber($this->container, $this->em));
}
4º) 此表单订阅者订阅 preSetData FormEvent。在这种方法中,我获得了与表单关联的实体,并获得了为其创建的所有自定义字段。 然后我在 Symfony2 Form Type 的帮助下将此字段添加到表单中。 一切顺利,当我显示我的表单时,自定义字段呈现正确。仅作记录,当我保存表单时,自定义字段中插入的值也可以很好地存储。
public function preSetData(FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
// During form creation setData() is called with null as an argument
// by the FormBuilder constructor. You're only concerned with when
// setData is called with an actual Entity object in it (whether new
// or fetched with Doctrine). This if statement lets you skip right
// over the null condition.
if (null === $data) {
return;
}
$formEntity = $form->getConfig()->getType()->getInnerType()->getEntity();
$DbEntity = $this->em->getRepository('AppCoreSchemaBundle:DbEntity')->findOneBy(array('id' => $formEntity));
if ($DbEntity && $DbEntity->getAllowCustomFields()) {
$organization = $this->container->get('app_user.user_manager')->getCurrentOrganization();
if (!$organization) {
throw $this->createNotFoundException('Unable to find Organization entity.');
}
$params = array(
'organization' => $organization,
'entity' => $DbEntity,
);
$entities = $this->em->getRepository('AppCoreSchemaBundle:DbCustomField')->getAll($params);
# RUN BY ALL CUSTOM FIELDS AND ADD APPROPRIATE FIELD TYPES AND VALIDATORS
foreach ($entities as $customField) {
# configurate customfield
FieldConfiguration::configurate($customField, $form);
# THE PROBLEM IS HERE
# IF OBJECT IS NOT NULL THEN MAKE SET DATA FOR APPROPRIATED FIELD
if ($data->getId()) {
$filters = array(
'custom_field' => $customField,
'object' => $data->getId(),
);
$DbCustomFieldValue = $this->em->getRepository('UebCoreSchemaBundle:DbCustomFieldValue')->getFieldValue($filters);
if ($DbCustomFieldValue) {
$form[$customField->getFieldAlias()]->setData($DbCustomFieldValue->getValue());
} else {
$form[$customField->getFieldAlias()]->setData(array());
}
}
}
}
}
问题是当我尝试编辑表单时。如果您查看上面代码中“问题在这里”的部分,您就可以理解。
如果表单的对象有一个 ID,那么我将获取为该对象的自定义字段存储的值,我调用 $form[field_alias']->setData(从映射为类型的数据库返回的值数组)。
但这不起作用,并且没有为字段设置数据。但如果在我的控制器中我也这样做,则数据设置正确。
有人知道问题出在哪里吗? preSetData 事件中不能设置数据吗?
已编辑
Entity DbCustomField 中的 value 字段是这样映射的:
/**
* @var string
*
* @ORM\Column(name="value", type="array", nullable=true)
*/
protected $value;
`
var_dump($DbCustomFieldValue) -> 对象(Ueb\Core\Bundle\SchemaBundle\Entity\DbCustomFieldValue)
var_dump(DbCustomFieldValue->getValue())
-> 字符串(11)“布鲁诺勇气”
但即使我尝试类似:
var_dump($customField->getFieldAlias()); = string(21) "testebruno-1383147874"
$form[$customField->getFieldAlias()]->setData('example1'); 不行。
但是在我的控制器中,如果我对上面的 fieldAlias 执行以下操作:
$form['testebruno-1383147874']->setData('example2');
-> 确实有效
有什么想法吗?
【问题讨论】:
-
我没有在你的代码中看到任何额外的东西,尝试用 die(var_dump($data)) 调试它,这样我们就可以看到你的数据数组值是什么
-
@metalvarez 检查我的编辑
-
几天前我遇到了同样的问题,我设法通过更改表单事件来解决它,当您在 preSetData 事件中设置值时,symfony2 将设置数据并且它可能会改变你之前在 preSetData 事件中设置的内容,如果可以的话,将事件更改为 postSetData,这就是我解决它的方法,所以我希望这对你有用。
-
谢谢,我会尝试使用 postSetData 事件
-
@metalvarez 我尝试了 postSetData 事件,它按我的预期工作。感谢您的提示;)
标签: php forms symfony doctrine-orm symfony-forms