我在Symfony窗體中有一個類型選擇元素的集合字段。每個元素應該有不同的列表選項。我如何安排在Symfony2中?我不能使用choices
選項,因爲每個元素都有相同的選項。我見過choice_list選項,它帶有一個可以產生選項列表的對象,但我不明白它如何爲集合中的不同元素產生不同的選擇。有沒有可能讓Symfony2形式的收藏領域有不同的選擇?
任何想法如何處理?
我在Symfony窗體中有一個類型選擇元素的集合字段。每個元素應該有不同的列表選項。我如何安排在Symfony2中?我不能使用choices
選項,因爲每個元素都有相同的選項。我見過choice_list選項,它帶有一個可以產生選項列表的對象,但我不明白它如何爲集合中的不同元素產生不同的選擇。有沒有可能讓Symfony2形式的收藏領域有不同的選擇?
任何想法如何處理?
我認爲你需要表單事件:http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html。
要更改收集的默認方式。
主要形式是簡單的:
namespace Acme\Bundle\AcmeBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Acme\Bundle\AcmeBundle\Form\DescriptorDumpFieldsType;
class TranscodingType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('descriptorDumpFields', 'collection', array('type' => new DescriptorDumpFieldsType()));
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Acme\Bundle\AcmeBundle\Entity\Descriptor',
);
}
public function getName()
{
return 'descriptor';
}
}
只是一個簡單的表格的子窗體的集合。
第二個使用處理表單創建的表單訂戶。 (使用表單事件)
因此,第一種形式正常創建並添加許多動態創建的DescriptorDumpFieldsType。
namespace Acme\Bundle\AcmeBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormTypeInterface;
use Acme\Bundle\AcmeBundle\Form\EventListener\TranscodingSubscriber;
class DescriptorDumpFieldsType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$subscriber = new TranscodingSubscriber($builder->getFormFactory());
$builder->addEventSubscriber($subscriber);
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Acme\Bundle\AcmeBundle\Entity\DescriptorDumpField',
);
}
public function getName()
{
return 'desc_dump_field';
}
}
形式訂閱:
namespace Acme\Bundle\AcmeBundle\Form\EventListener;
use Symfony\Component\Form\Event\DataEvent;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;
use Acme\Bundle\AcmeBundle\Entity\DumpField;
use Acme\Bundle\AcmeBundle\Form\Transcoding\DataTransformer\JsonToHumanDateTransformer;
class TranscodingSubscriber implements EventSubscriberInterface
{
private $factory;
public function __construct(FormFactoryInterface $factory)
{
$this->factory = $factory;
}
public static function getSubscribedEvents()
{
return array(FormEvents::SET_DATA => 'setData');
}
public function setData(DataEvent $event)
{
$data = $event->getData();
$form = $event->getForm();
if (!is_null($data)) {
$this->buildForm($data, $form);
}
}
protected function buildForm($data, $form)
{
switch ($data->getDumpField()->getType()) {
case DumpField::TYPE_ENUM:
$type = 'enum'.ucfirst($data->getDumpField()->getKey());
$class = 'dump_field_'.strtolower($data->getDumpField()->getKey());
$form->add($this->factory->createNamed('collection', 'transcodings', null, array('required' => false, 'type' => $type, 'label' => $data->getDumpField()->getKey(), 'attr' => array('class' => $class))));
break;
case DumpField::TYPE_DATE:
$transformer = new JsonToHumanDateTransformer();
$class = 'dump_field_'.strtolower($data->getDumpField()->getKey());
$builder = $this->factory->createNamedBuilder('human_date', 'params', null, array('label' => $data->getDumpField()->getKey(), 'attr' => array('class' => $class)));
$builder->prependNormTransformer($transformer);
$form->add($builder->getForm());
break;
}
}
}
所以,你可以定製你想要的方式,在buildForm集合的每個子表單。
感謝toine,爲我工作。 – ninsky 2015-04-25 16:11:03
你能告訴我們你的具體情況嗎?你想要完成什麼?我不太明白你的意思... – 2012-01-17 16:51:01
像上面一樣,我不太明白你的意思。也許你可以在表單中使用__construct來根據你正在處理的'數據對象'的對象傳遞選項到表單。 – 2012-01-22 12:49:25