【问题标题】:How to get symfony 2 forms to return entities from a dynamic value如何获取 symfony 2 表单以从动态值返回实体
【发布时间】:2013-03-02 01:17:02
【问题描述】:

好的,这里是我正在尝试做的快速概述。我有一个与“ClientDomain”实体有关系的“Client”实体。我需要有一个表单来显示给定客户端的所有 ClientDomain 列表。在控制器中,我知道我需要过滤哪些客户端,但我不确定如何将该信息传递给 formBuilder。

这是我目前所拥有的:

//src/NameSpace/ClientBundle/Entity/Client.php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Client{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $client_id;

/**
 * @ORM\Column(type="string")
 */
protected $name;

/**
 * @ORM\OneToMany(targetEntity="ClientDomain", mappedBy="client")
 */
protected $domains;

...
}

还有形式:

//src/LG/ClientBundle/Form/ClientDomainSelectionForm.php
namespace LG\ProjectBundle\Form\Projects;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class ClientDomainSelectionForm extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('client_domain', 'entity', array(
            'class' => 'LG\ClientBundle\Entity\ClientDomain',
            'query_builder'=> function(EntityRepository $er) {
                return $er->createQueryBuilder('cd')
                /* NEEDS TO FIND DOMAINS BY CLIENT X */
            },
            'property' => 'domain',
            'label' => 'Domain: '
        ));
    }
}

最后是控制器:

//src/LG/ClientBundle/Controller/DomainSelectorController.php
namespace LG/ClientBundle/Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; 

use LG\ClientBundle\Entity\Client;
use LG\ClientBundle\Entity\ClientDomain;
use LG\ClientBundle\Entity\ClientActiveDomain;
use LG\ClientBundle\Form\ClientDomainSelectionForm;


/**
 * @Route("")
 */
class DomainSelectorController extends Controller{

    /**
     * @Route("/client/{client_slug}/select-domain", name="lg.client.clientdomainselection.selectclient")
     * @Template
     */
    public function selectDomainAction(Request $request, Client $client){
        $activeDomain = new ClientActiveDomain();
        $form = $this->createForm(new ClientDomainSelectionForm(), $activeDomain );
        if ($request->isMethod('POST')) {
            $form->bind($request);
            if ($form->isValid()) {
                $em = $this->getDoctrine()->getEntityManager();
                $em->persist($activeDomain );
                $em->flush();
                return $this->redirect(/*huge long url*/);
            }
        }
        return array(
            'form' => $form->createView(),
        );
    }

}

如您所见,我可以访问控制器中的客户端实体,但我不确定如何将其提供给表单构建器,以便它只返回当前客户端的域。

【问题讨论】:

    标签: php symfony doctrine-orm symfony-forms


    【解决方案1】:

    我已经找到答案了,你只需要在表单中添加一个构造函数,然后像这样从控制器传入客户端:

    //src/LG/ClientBundle/Form/ClientDomainSelectionForm.php
    namespace LG\ProjectBundle\Form\Projects;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    
    class ClientDomainSelectionForm extends AbstractType {
    
        protected $client;
    
        public function __construct(Client $client) {
            $this->client = $client;
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $client = $this->client;
            $builder->add('client_domain', 'entity', array(
                'class' => 'LG\ClientBundle\Entity\ClientDomain',
                'query_builder'=> function(\Doctrine\ORM\EntityRepository $er) use ($client) {
                    return $er->createQueryBuilder('cd')
                        ->where('cd.client = :client')
                        ->orderBy('cd.domain', 'ASC')
                        ->setParameter('client',$client->getClientId());
                },
                'property' => 'domain',
                'label' => 'Domain: '
            ));
        }
    }
    

    然后在控制器中:

    //src/LG/ClientBundle/Controller/DomainSelectorController.php
    
    ...
    
    public function selectDomainAction(Request $request, Client $client){
    
        ...
    
        $form = $this->createForm(new ClientDomainSelectionForm($client), $activeDomain );
    
        ...
    }
    
    ...
    

    【讨论】:

    • 其实你应该创建一个必需的选项client而不是使用构造函数,因为构造函数在创建表单的第一个实例时只被调用一次。因此,如果您有两个具有不同客户端的表单,它们将绑定到第一个表单的客户端。另一方面,选项不共享。
    • 客户端只需要在创建时设置。一旦完成,实体的所有编辑都是可能的,因为教义已经知道客户。但我可以看到您的用例可能在另一个应用程序中发生的位置。感谢您的意见。
    猜你喜欢
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    • 2017-02-05
    • 2019-06-16
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多