Сгенерировать один и тот же тип формы на одной странице несколько раз Symfony2

Я пытаюсь создать тип формы, в частности, «ProductLanguageType».

Я хочу генерировать ProductLanguageType столько раз, сколько текущих номеров существующих языков в таблице Language.

Например, если у меня есть (английский, французский, русский, китайский) в таблице Language, он будет генерировать 4 ProductLanguageType формы на той же странице.

Я хотел бы знать, как я могу запросить таблицу языков и сгенерировать несколько форм одного и того же типа на одной странице, является ли создателем формы, способным это сделать, или есть другой способ обхода? Были некоторые проблемы с этим в течение некоторого времени и были бы рады найти хорошее решение для этого.

ProductLanguageType:

class ProductLanguageType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options){ $builder->add('id_language', 'entity', array( 'class' => 'AdminBundle:Language', 'data_class' => 'Main\AdminBundle\Entity\Language', 'property' => 'language' ) ) ->add('name', 'text') ->add('description', 'ckeditor', array( 'config_name' => 'admin', 'config' => array( 'filebrowser_image_browse_url' => array( 'route' => 'elfinder', 'route_parameters' => array('instance' => 'default'), ), ) )) ->add('short_description', 'text'); } public function getName(){ return 'productLanguage'; } } 

ProductType (ProductLanguageType встроен здесь):

 class ProductType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options){ $builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData')); $builder->add('productLanguage', new ProductLanguageType()) ->add('id_seller','text') ->add('price','text') ->add('cost_price','text') ->add('retail_price','text') ->add('hot', 'checkbox') ->add('featured', 'checkbox') ->add('new', 'checkbox') ->add('free_shipping', 'checkbox') ->add('status','text') //active or inactive, to be decided if hidden or visible ->add('Add', 'submit'); } } 

Надеюсь, это поможет кому-то.

Правильный способ будет заключаться в использовании службы form.factory Symfony для создания именованного строителя и, в свою очередь, создания формы из этого. Я рекомендую создать функцию для процесса создания формы, поскольку (как я понимаю, исправьте меня, если я ошибаюсь), каждый экземпляр FormBuilder должен быть другим, чтобы создать другую форму.

Также как объяснение цели кода: мне нужно было показать список открытых билетов в справочной системе с возможностью назначить человека (авторизованного без входа в систему) на основе своего токена входа в билет. Это необходимо для отображения N форм на одной странице, которые будут уникальными, но сгенерированы из одного «шаблона» или «Тип», если вы это сделаете.

Этот код достиг этого без каких-либо взломов. Для создания формы с конкретным идентификатором (имя) от контроллера AFAIK просто нет сокращенного метода.

ех.

 public function generateFormForTicketAssignment(Ticket $ticket) { $ticketAssignType = new TicketAssignInvokeType(); $ticketAssignType->setNameSuffix($ticket->getId()); /** * @var Symfony\Component\Form\FormBuilderInterface */ $builder = $this->get('form.factory')->createNamedBuilder($ticketAssignType->getName(), $ticketAssignType ); $builder->setAutoinitialize(true); $formTicket = $builder->getForm(); $formTicket->get('ticket')->setData($ticket); return $formTicket; } 

И (это важная часть) ticketAssignInvokeType выглядит так:

 class TicketAssignInvokeType extends AbstractType { private $nameSuffix = null; private $name = 'ticket_assign_invoke'; public function __constructor(string $suffix = null) { //parent::__construct(); $this->nameSuffix = $this->generateNameSuffix(); } private function generateNameSuffix() { if ($this->nameSuffix == null || $this->nameSuffix == '') { $generator = new SecureRandom(); //change data to alphanumeric string return bin2hex($generator->nextBytes(10)); } return $this->nameSuffix; } /** * * @param string $suffix When set suffix added to form will use selected * string (note it should be unique for all forms on a page). */ public function setNameSuffix($suffix){ $this->nameSuffix = $suffix; } public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('loginToken',new AuthenticateTokenType()) ->add('ticket',new TicketIDType()) ->add('save', 'submit', array('label' => 'form.button.assign')) ; } public function getName() { if ($this->nameSuffix == null || $this->nameSuffix == "" ) { $this->nameSuffix = $this->generateNameSuffix(); } return $this->name .'_'. $this->nameSuffix; } public function configureOptions(OptionsResolver $resolver) { // ... } } 

Это несколько чрезмерно сложная логика и тестирование суффикса имени, но в какой-то момент я не мог понять, почему все, что я делаю, это имя формы без суффикса, следовательно, сложность.

PS. Я создал формы в качестве сервисов и позже проверю, можно ли использовать сервис, а это было моим первым намерением.

PS2. Я еще не уверен в методе setAutoinitialize , но также проверю его.

Теперь в Symfony 3.0 они изменили createNamedBuilder, поэтому можно решить это, только позвонив:

 use AppBundle\Form\ShippingTrackCodeReturnType; $uniqueForm = $this->get('form.factory')->createNamedBuilder('ship_form_'.$orderRecord->getId(), ShippingTrackCodeReturnType::class, $orderRecord)->getForm(); 

Таким образом, вам просто нужно зацикливать, чтобы отображать и сохранять их:

 foreach ($invoice->getOrderRecords() as $key => $orderRecord) { // creates the forms with different names $returnShipTrackCodeForm = $this->get('form.factory')->createNamedBuilder('ship_form_'.$orderRecord->getId(), ShippingTrackCodeReturnType::class, $orderRecord)->getForm(); $returnShipTrackCodeForm->handleRequest($request); if ($returnShipTrackCodeForm->isSubmitted() && $returnShipTrackCodeForm->isValid()) { // flush object } $returnForms[$orderRecord->getId()] = $returnShipTrackCodeForm; }