尽管这是一个老问题,以为我反正回答。以前的答案不使用Doctrine的ObjectSelect
。
你说有OneToOne关系,不希望记录添加到“单表”;我假设你在这里有一个Uni-directional OneToOne的关系。
但是,如果你有“产品”和“品牌”作为实体OneToMany Bi-directional关系可能更适合;)
与OneToOne然而去,你的实体应该是这样的:
class Brand {
/**
* @var int
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @var string
* @ORM\Column(name="name", type="string", nullable=false, length=128)
*/
protected $name;
//Getters/Setters
}
class Product {
/**
* @var int
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @var string
* @ORM\Column(name="name", type="string", nullable=false, length=128)
*/
protected $name;
//Change below "OneToOne" to "ManyToOne" for proper product + brand relationship. Just this change will leave it as uni-directional.
/**
* @var Brand
* @ORM\OneToOne(targetEntity="Brand", fetch="EAGER")
* @ORM\JoinColumn(name="brand", referencedColumnName="id")
*/
protected $brand;
//Getters/Setters
}
假设你的实体是正确的,你应该使用ObjectSelect
构建成Doctrine。
class ProductForm
{
/** @var ObjectManager */
protected $objectManager;
public function __construct($name = 'product-form', $options = [])
{
parent::__construct($name, $options);
}
public function init()
{
$this->add([
'type' => 'DoctrineModule\\Form\\Element\\ObjectSelect',
'name' => 'brand',
'required' => true,
'attributes' => [
'id' => 'selectBrand',
'multiple' => false,
'value' => null,
],
'options' => [
'label' => 'Select brand',
'object_manager' => $this->getObjectManager(),
'target_class' => Brand::class,
'property' => 'id',
'is_method' => true,
'find_method' => [
'name' => 'findBy',
'params' => [
'criteria' => [],
'orderBy' => ['name' => 'ASC'],
],
],
'empty_option' => '--- Select Brand ---',
'label_generator' => function (Brand $entity) {
return $entity->getName();
}
],
]);
}
/**
* @return ObjectManager
*/
public function getObjectManager()
{
return $this->objectManager;
}
/**
* @param ObjectManager $objectManager
*/
public function setObjectManager(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
}
}
确保设置Module.php
以便能够加载此表单。将getServiceConfig()
函数添加到它。
public function getServiceConfig()
{
/** @var ServiceManager $sm */
return [
'factories' => [
'product_form' => function ($sm)
{
$form = new ProductForm();
$form->setInputFilter(new ProductInputFilter());
/** @var EntityManager $entityManager */
$entityManager = $sm->get('doctrine.entitymanager.orm_default');
//Set Doctrine ObjectManager
$form->setObjectManager($entityManager);
//Set Doctrine Object as Hydrator
$form->setHydrator(new DoctrineObject($entityManager, Product::class));
//Set Doctrine Entity
$form->setObject(new Product());
//Initialize elements onto form
$form->init();
return $form;
},
],
];
}
}
接下来,在Controller中加载表单。
$form = $this->getServiceLocator()->get('product_form');
===========================
注:这工作,直到Zend框架2.5.2
有关如何使用ZF2水合器获得此项工作的任何更新?我正在实现一个hack,它可以从一个实体手动构造一个数组,并使用'setValueOptions'来设置它。你如何链接关联的实体与选择下拉菜单?例如:用户可以有多个客户端(ManyToMany),所以当我编辑用户时,我需要一个'
@hohner只需查看DoctrineModule的文档(github上的docs文件夹),Bakura写了一篇惊人的自述文件;) – Sam 2013-02-05 18:39:38