2011-07-16 29 views
35

Tôi đang sử dụng danh sách lựa chọn thực thể trong biểu mẫu của tôi. Tôi chỉ muốn sử dụng các thực thể cụ thể (ví dụ: chỉ những nhóm mà người dùng đó thuộc về) Vì vậy, trong bộ điều khiển, tôi nhận được các nhóm này và cố gắng chuyển chúng thành formBuider.Symfony 2 - cách chuyển dữ liệu sang formBuilder?

Bộ điều khiển:

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

như vậy, những gì bây giờ? làm thế nào để sử dụng nó trong formBuilder? làm thế nào để thay đổi dòng này để sử dụng mảng thông qua các nhóm?

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

hoặc theo cách khác:

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 
    ; 
    } 
/.../ 
} 

vậy làm thế nào tôi có thể có được đối tượng $ dùng sử dụng theo hình thức xây dựng? ($ User đại diện cho người dùng đăng nhập hiện hành)

+2

tôi đã hỏi cùng một câu hỏi: - http: // stackoverflow.com/questions/7807388/passing-data-from-controller-to-type-symfony2 giải pháp của vi khuẩn thực sự tốt !!! : thumbsup: – xeon

+0

Nếu bạn cần thực hiện truy vấn, thực hiện cuộc gọi api, v.v. để hiển thị chế độ xem, thì bạn đang làm sai. Nếu đây là một ràng buộc mà symfony đặt trên khung công tác (không có cách nào khác để cung cấp dữ liệu tùy ý cho trình tạo biểu mẫu) thì hãy xấu hổ về chúng. Đây là công việc được xác định rõ ràng của bộ điều khiển. – eggmatters

Trả lời

2

Nếu bạn muốn sử dụng truy vấn tùy chỉnh, bạn phải thiết lập query_builder tùy chọn như sau:

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(); 

Bạn có thể tìm thêm thông tin về xây dựng truy vấn trong Doctrine manual và về các lựa chọn cho entity trong Symfony2 manual.

+0

Có, tôi biết cách sử dụng truy vấn tùy chỉnh, nhưng làm cách nào tôi có thể sử dụng nó khi tôi muốn nhận các nhóm người dùng đã đăng nhập hiện tại? tôi phải khai báo một container trong một loại hình thức lớp học? ví dụ: trong điều khiển im sử dụng '$ this-> get ('security.context') -> getToken() -> getUser()' – jacobmaster

+1

Tôi khuyên bạn nên sử dụng mối quan hệ ManyToOne hoặc ManyToMany tại đây. Nó sẽ làm mọi thứ trở nên dễ dàng hơn nhiều. –

+0

tôi đặt câu hỏi cụ thể hơn. có lẽ bây giờ bạn có thể giúp tôi ... – jacobmaster

28

Bạn có thể cung cấp đối tượng bạn muốn sử dụng trong phương thức __construct().

Ví dụ:

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

Trong loại hình của bạn:

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

Và sau đó trong kiểu mẫu của bạn trong phương pháp buildForm: giải pháp

$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

Bacteries' là một trong những tốt thực . Chỉ cần một lưu ý để lưu nhức đầu cho người khác như tôi :)

Trong phần này tôi có thể chỉ ra phần use ($company). Nó đã được ẩn bởi khung và tất nhiên không có gì hoạt động đúng mà không có nó.

$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

Cách tốt nhất (ý kiến ​​của tôi) được cung cấp cho thực thể biểu mẫu của bạnQuản lý và chọn tất cả những gì bạn cần trong đó. Nhưng đừng quên khai báo khóa rỗng trong setDefaults() nếu không dữ liệu sẽ không chuyển tới builder của bạn.

Something như thế này một

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 
     )); 
} 

Áp dụng EM tùy chọn như đơn giản ... giải pháp

+0

Điều này không đánh bại mục đích của một ứng dụng MVC? Tôi nghĩ toàn bộ quan điểm của một khuôn khổ là che khuất lớp dữ liệu khỏi lớp kết xuất. Giống như, càng nhiều càng tốt. – eggmatters

+0

Symfony2 kích thích tất cả các mẫu mà bạn biết ... Vì vậy, đừng ngạc nhiên. Tôi đã cho thấy giải pháp làm việc cho tôi, sf2 là một mvc xấu để phát triển nếu bạn muốn làm việc với các mẫu. Nếu bạn thanh lịch hơn - hãy sử dụng của bạn ... – 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

Bacteries' KHÔNG PHẢI LÀ tốt nhất. Ví dụ, nếu bạn khai báo kiểu của bạn là dịch vụ, không thể truyền một đối tượng cho hàm tạo.

Giải pháp hoàn hảo là các tùy chọn - chỉ cần chuyển dữ liệu dưới dạng tùy chọn để tạo trình tạo.

+0

Ngoài ra, giải pháp của anh ta sẽ phá vỡ ở mức 3.0 vì các loại được xây dựng bởi FQCN – Ryall

Các vấn đề liên quan