2011-07-16 1 views
35

Я использую список выбора сущности в своей форме. Я хочу использовать только определенные объекты (например, только группы, к которым принадлежит пользователь) Итак, в контроллере я получаю эти группы и пытаюсь передать их в formBuider.Symfony 2 - как передать данные formBuilder?

Контроллер:

/.../ 
$groups = $em->getRepository('VendorMyBundle:Group')->getUserGroups($user); 
$form = $this->createForm(new Message($groups), $message); 
/.../ 

так, что теперь? как использовать его в formBuilder? Как изменить эту строку для использования переданного массива групп?

->add('group','entity',array('class' => 'Vendor\MyBundle\Entity\Group', 'label'=>'Group:')) 

или другим способом:

class MessageType 
{ 
/.../ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
    $builder 
     ->add('group','entity', 
     array(
      'class' => 'Vendor\MyBundle\Entity\Group', 
      'property' => 'name', 
      'query_builder' => function ($repository) { 
      $qb = $repository->createQueryBuilder('group'); 
      $qb->add('where', 'group.administrator = :user'); 
      $qb->setParameter('user', $user->getId()); 
      return $qb; 
      }, 
      'label' => 'Group' 
     ) 
    ) 
     // Continue adding fields 
    ; 
    } 
/.../ 
} 

так, как я могу получить объект $ пользователю использовать в виде строителя? ($ Пользователей представляют текущий пользователь вошедший)

+2

Я задал тот же вопрос: - http: // stackoverflow.com/questions/7807388/pass-data-from-controller-to-type-symfony2 решение Bacteries действительно хорошо !!! : thumbsup: – xeon

+0

Если вам нужно выполнить запросы, сделайте вызовы api и т. Д., Чтобы сделать вид, тогда вы делаете это неправильно. Если это ограничение, которое Symfony помещает в фреймворк (нет другого способа предоставить произвольные данные в построитель форм), тогда стыдитесь за них. Это четко определенная задача контроллера. – eggmatters

ответ

2

Если вы хотите использовать пользовательский запрос, вы должны установить query_builder опцию следующим образом:

use Doctrine\ORM\EntityRepository; 

... 

$message = new Message(); 

$form = $this->createFormBuilder($message) 
      ->add('group', 'entity', array(
        'class' => 'Vendor\MyBundle\Entity\Group', 
        'label'=>'Group:', 
        'query_builder' => function(EntityRepository $er) { 
         return $er->createQueryBuilder('g') 
           ->... // whatever you want to do 
         } 
        )) 
      ->getForm(); 

Вы можете найти более подробную информацию о построителе запросов в Doctrine manual и о вариантах entity в Symfony2 manual.

+0

Да, я знаю, как использовать пользовательский запрос, но как я могу его использовать, когда хочу получить группы текущего пользователя? я должен объявить контейнер в классе типа формы? ex: в контроллере im using' $ this-> get ('security.context') -> getToken() -> getUser() ' – jacobmaster

+1

Я бы рекомендовал использовать отношения ManyToOne или ManyToMany здесь. Это упростит ситуацию. –

+0

Я задаю свой вопрос более конкретно. возможно, теперь вы можете мне помочь ... – jacobmaster

28

Вы можете указать объект, который хотите использовать в методе __construct().

Например:

$form = $this 
    ->get('form.factory') 
    ->create(new ApplyStepOneFormType($this->company, $this->ad), $applicant); 

В вашем типе формы:

function __construct(\Your\Bundle\Entity\Company $company, \DYB\ConnectBundle\Entity\Ad $ad) { 
    $this->company = $company; 
    $this->ad = $ad; 
} 

И тогда в вашем типе формы в методе buildForm: раствором

$company = $this->company;  
$builder->add('ad', 'entity', array(
    'class' => '\Your\Bundle\Entity\Ad', 
    'query_builder' => function(\Your\Bundle\Repository\AdRepository $er) use ($company) { 
     return $er->getActiveAdsQueryBuilder($company); 
    }, 
)); 
2

Биологических продукты является очень хорошим один , Просто заметьте, чтобы сохранить головную боль другому парню, как я :)

В этой части я могу указать часть use ($company). Он был спрятан рамкой и, конечно, ничего не работает нормально.

$builder->add('ad', 'entity', array(
    'class' => 
     '\Your\Bundle\Entity\Ad', 
    'query_builder' => 
     function(\Your\Bundle\Repository\AdRepository $er) use ($company) { 
      return $er->getActiveAdsQueryBuilder($company); 
     }, 
    ) 
); 
0

Лучший способ (мое мнение) - предоставить вашей форме entityManager и выбрать все, что вам нужно. Но не забудьте объявить пустой ключ в setDefaults(), иначе данные не будут переданы вашему строителю.

Что-то как этот

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $options['em']->getRepository(''); // select all you need 
    $builder->add('title', 'text') 
      ->add('content', 'textarea'); 
} 

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'Main\BlogBundle\Entity\Post', 
     'validation_groups' => array('post'), 
     'required' => false, 
     'em' => null // this var is for your entityManager 
     )); 
} 

Применение EM в качестве простой вариант ... решение

+0

Разве это не побеждает цель приложения MVC? Я думал, что весь смысл структуры заключается в том, чтобы заслонить слой данных из слоя рендеринга. Похоже, насколько это возможно. – eggmatters

+0

Symfony2 бросит все шаблоны, которые вы знаете ... Так что не удивляйтесь. Я показал решение, которое сработало для меня, sf2 - плохой mvc для разработки, если вы хотите работать с шаблонами. Если у вас более элегантный - используйте свой ... – user1954544

11
//In controller pass the value which you want to use in builder form in array like 

$object = new Question(); 
$form->create(new QuestionType() , $object , array('sqtname'=>2,'question_type'=>2)); 


//In Form type class 
public function buildForm(FormBuilderInterface $builder , array $options) 
    { 
    //for setting data field dynamically 
    if (array_key_exists('question_type', $options) && $options['question_type'] != '') { 
    $data = $em->getReference("RecrutOnlineStandardBundle:StdQuestionType",$options['question_type']->getId()); 
    } else { 
    $data = ""; 
    } 


    $builder->add('StdQuestionType', 'entity', array(
     'class' => 'TestStandardBundle:StdQuestionType', 
     'property' => 'name', 
     'empty_value' => 'Sélectionner un question type', 
     'required' => true, 
     'data' => $data, 
     'query_builder' => function(EntityRepository $er) use ($options) { 
      if (isset($options['sqtname']) && $options['sqtname'] != '') { 
       return $er->createQueryBuilder('sqt') 
           ->where("sqt.name!= ".$options['sqtname']); 
      } else{ 
       return $er->createQueryBuilder('sqt'); 
      } 
     } 
    )); 
} 

public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
     'data_class' => 'Test\QuestionBundle\Entity\Question', 
     'required' => false, 
     'sqtname' => '', 
     'question_type' =>'' 
     )); 
    } 
3

Биологические продукты НЕ хороший. Например, если вы объявляете свой тип как службу, невозможно передать объект конструктору.

Идеальное решение - это опции - просто передайте данные в качестве опции для формирования строителя.

+0

Также его решение будет разбиваться на 3.0, поскольку типы создаются FQCN – Ryall