我将逐步学习如何使用数据转换器
问题是,如果我想对Choice类型执行此操作,该怎么办?我用jQuery动态填充哪个?
我测试了他们提供的示例(没有创建自定义类型..),它100%适用于文本字段类型,但一旦我将其更改为choice并给它空的选项,它就不起作用了,这与我在加载页面后用jQuery填充选项有关吗?
示例
模型[选择已加载查询生成器的模型实体和实体字段类型…]
Number[一开始是空的选择,当模型更改时,我会对该模型的编号发出AJAX请求]
如果我将数字保留为文本字段,并手动键入一个有效的数字(查看数据库),它会起作用,但如果我将其留给jQuery和Choice类型,它会返回一个表单错误,其中包含无效的Model值。
在这两种情况下,我都在处理表单之前执行print_r($request->request),在这两个情况下,它都提交Number=>1,这在本例中是正确的,但不知何故,当数据类型为Choice时,它并没有转换数据,而当它的Text时,它会转换数据。
这就是jQuery填充数字选择框数据的方式:
<option value=”1”>1234ABCDEFG</option>
顺便说一句,我正在用Id进行转换,这将是所选选项的值。
好的。您需要做的是倾听preSubmit表单事件,然后通过将提交的值添加到您的choice元素来基本上接受它。
http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-表单事件提交数据
==============================================
我没有看你的粘贴箱,但这里有一个似乎对我有用的例子。这是一个简单的性别选择列表,我在其中添加了另一个客户端选项。preSubmit监听器只需将默认的性别选择选项替换为包含所提交内容的选项。您应该能够添加数据转换的内容,并做好准备。
namespace CeradBundleTournBundleFormTypeTest;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentFormFormFactoryInterface;
use SymfonyComponentFormFormEvent;
use SymfonyComponentFormFormEvents;
use SymfonyComponentEventDispatcherEventSubscriberInterface;
class DynamicFormType extends AbstractType
{
public function getName() { return 'cerad_tourn_test_dynamic'; }
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('gender', 'choice', array(
'choices' => array('m' => 'Male', 'f' => 'Female'),
'required' => false,
));
$builder->addEventSubscriber(new DynamicFormListener($builder->getFormFactory()));
}
}
class DynamicFormListener implements EventSubscriberInterface
{
private $factory;
public function __construct(FormFactoryInterface $factory)
{
$this->factory = $factory;
}
public static function getSubscribedEvents()
{
return array(
FormEvents::PRE_SUBMIT => 'preSubmit',
FormEvents::PRE_SET_DATA => 'preSetData',
);
}
public function preSetData(FormEvent $event)
{
// Don't need
return;
}
public function preSubmit(FormEvent $event)
{
$data = $event->getData();
$gender = $data['gender'];
if (!$gender) return; // If nothing was actually chosen
$form = $event->getForm();
/* =================================================
* All we need to do is to replace the choice with one containing the $gender value
* Once this is done $form->isValid() will pass
*
* I did attempt to just add the option to the existing gender choice
* but could not see how to do it.
* $genderForm = form->get('gender'); // Returns a Form object
* $genderForm->addNewOptionToChoicesList ???
*
* Might want to look up 'whatever' but that only comes into play
* if the form fails validation and you paas it back to the user
* You could also use client side javascript to replace 'whatever' with the correct value
*/
$form->add($this->factory->createNamed('gender','choice', null, array(
'choices' => array($gender => 'whatever'),
'required' => false,
'auto_initialize' => false,
)));
return;
}
}