我正在尝试创建一个动态加载与“项目”相关的所有“网站”的表单,似乎this会有用,所以我试了一下:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
class EngineeringType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('project','entity',array(
'class' => 'tBundle:Project',
'label' => 'Project'
;
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
$sites = $data->getProject()->getSites();
$form->add('site', 'entity', array('choices' => $sites));
}
);
}
当我尝试访问表单时出现问题,我得到:
FatalErrorException: Error: Call to a member function getSites() on a non-object in ... tBundle\Form\EngineeringType.php line 41
以下是我的实体:
namespace tBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Engineering
*
* @ORM\Table(name="engineerings")
* @ORM\Entity
*/
class Engineering
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="tBundle\Entity\Project")
* @ORM\JoinColumn(name="project_id", referencedColumnName="id",nullable=false)
*/
private $project;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set project
*
* @param string $project
* @return Engineering
*/
public function setProject(\tBundle\Entity\Project $project)
{
$this->project = $project;
return $this;
}
/**
* Get project
*
* @return string
*/
public function getProject()
{
return $this->project;
}
项目:
命名空间tBundle \ Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Project
*
* @ORM\Table(name="projects")
* @ORM\Entity
*/
class Project
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\ManyToMany(targetEntity="tBundle\Entity\Site")
* @ORM\JoinTable(name="project_sites",
* joinColumns={@ORM\JoinColumn(name="site_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="project_id", referencedColumnName="id")}
* )
*/
private $sites;
public function __construct()
{
$this->sites = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Project
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Get Sites
*
* @return array
*/
public function getSites()
{
return $this->sites;
}
/* Returns Project's Name */
public function __toString()
{
return $this->name;
}
我做错了什么?
修改
控制器:
/**
* Creates a form to create a Engineering entity.
*
* @param Engineering $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Engineering $entity)
{
$form = $this->createForm(new EngineeringType(), $entity, array(
'action' => $this->generateUrl('engineering_create'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Creates a form to edit a Engineering entity.
*
* @param Engineering $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Engineering $entity)
{
$form = $this->createForm(new EngineeringType(), $entity, array(
'action' => $this->generateUrl('engineering_update', array('id' => $entity->getId())),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
答案 0 :(得分:1)
PRE_SET_DATA事件实际上被触发了两次。第一次没有任何数据。手册中曾经有一个模糊的解释原因,但我再也找不到了。
所以只是:
function(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
if ($data)
{
$sites = $data->getProject()->getSites();
$form->add('site', 'entity', array('choices' => $sites));
}
}
=============================================== ======
更新了答案,展示了如何处理不存在的$ project:
if ($data)
{
$project = $data->getProject();
$sites = $project ? $project->getSites() : array();
$form->add('site', 'entity', array('choices' => $sites));
}
答案 1 :(得分:0)
有一个简单的解决方案,为什么不使用"属性"表单构建器上的属性?
$builder
->add('project','entity',array(
'class' => 'tBundle:Project',
'label' => 'Project',
'property' => 'sites');
如果这还不够,甚至可以使用查询构建器:
$builder->add('users', 'entity', array(
'class' => 'AcmeHelloBundle:User',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.username', 'ASC');
},
));
如果这还不够,你可以在这里找到更多描述: Symfony documentation
编辑:
所以你的问题是,使用第一个解决方案,它将成为一个数组,因此请使用我的第二个选项,并在查询构建器中指定将反映您需求的内容。 或者使用它,就像课程不是项目而是网站。