Doctrine orm Zend \与条令2和多通关系一起形成
今天我开始阅读Zend\Form的功能。我从Michael Gallego那里找到了一篇文章,他在文章中解释了如何使用一些新的很酷的功能 如果我们处理的是1-1关系,那么这个例子到目前为止效果很好。教义很好地涵盖了他们 我想做的是 我想要一个选择框,而不是用textarea作为相关值 选择框应具有有效选项,具体取决于数据库中的内容 为了以后进行编辑,需要选择当前选定的值 条令不应向一个表中添加新行 正如您在上所看到的,我使用了教程中的示例,但将其缩短为产品和品牌。在我的示例中,Brands是一个DB表,其中包含预定义的品牌Nike、Adidas、Puma等,当您从表单中创建新产品时,您可以将这些品牌作为选择菜单 现在,我添加选项的方式不起作用。我知道我可以用如下数组手动设置选项Doctrine orm Zend \与条令2和多通关系一起形成,doctrine-orm,zend-form,relationship,zend-framework2,Doctrine Orm,Zend Form,Relationship,Zend Framework2,今天我开始阅读Zend\Form的功能。我从Michael Gallego那里找到了一篇文章,他在文章中解释了如何使用一些新的很酷的功能 如果我们处理的是1-1关系,那么这个例子到目前为止效果很好。教义很好地涵盖了他们 我想做的是 我想要一个选择框,而不是用textarea作为相关值 选择框应具有有效选项,具体取决于数据库中的内容 为了以后进行编辑,需要选择当前选定的值 条令不应向一个表中添加新行 正如您在上所看到的,我使用了教程中的示例,但将其缩短为产品和品牌。在我的示例中,Brands是一个
$form->get('product')->get('brand')->setAttribute('options', array('Nike'=>'1', 'Adidas'=>'2', etc);
但我坚信有一种更自动化的方法可以做到这一点。我只是不理解Zend提供的所有这些内容或类
问题是,即使我如上所述手动定义数组,产品和品牌的映射也无法正常工作。现在的$product转储如下所示
object(Application\Entity\Product)[210]
protected 'id' => null
protected 'name' => string 'asdasd' (length=6)
protected 'price' => string '123123' (length=6)
protected 'brand' =>
object(Application\Entity\Brand)[215]
protected 'id' => null
protected 'name' => string '1' (length=1)
很明显,我想要实现的品牌完全错了,zend可能认为这是对的,因为我选择的值是1
问题:如何告诉表单将select值映射到映射的对象ID?尽管在这种情况下,我建立产品模型的方式可能是错误的
任何帮助都将不胜感激:查看您的BrandFieldSet,您只为InputFilterProvider指定了名称,因此永远不会传递id 其次,我会建议你删除注册表。使用ServiceManager创建的类可以/应该实现ServiceManagareAwareInterface,如果它们需要访问其他任何东西(如果不是使用构造函数指定的话) 因此,在控制器中而不是使用注册表访问服务管理器
$this->getServiceLocator()
->get('FQCN_OR_ALIAS');
这里有一些由框架贡献者编写的好例子,我将在这里列出一些github Repo
因为我没有名声,所以不能再发了
如果您还有任何问题,请访问irc.freenode.org上的zftalk.2加入我们这是来自我的表单对象的代码 我希望这会有帮助
class ProductForm extends Form
{
public function __construct($em)
{
parent::__construct();
$this->add(array(
'name' => 'productGroupId',
'attributes' => array(
'type' => 'select',
'label' => 'Category',
'options' => array(),
),
));
$this->setProductGropus($em->getRepository('Project\Entity\ProductGroup')->findAll());
public function setProductGropus($groups)
{
$groupsForm = array('--Select--'=>'');
foreach ($groups as $group) {
$groupsForm[$group->name] = (string) $group->productGroupId;
}
$this->get('productGroupId')->setAttribute('options',$groupsForm);
}
}
}
虽然这是个老问题,但我想我还是会回答的。前面的答案没有使用原则的定义
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;
}
}
您说有一个OneToOne关系,不希望将记录添加到一个表中;我假设你有一段感情
然而,如果你把产品和品牌作为一个实体,一种关系可能更合适
然而,使用OneTONE时,您的实体应如下所示:
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
}
假设您的实体是正确的,那么您应该使用内置原则
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;
},
],
];
}
}
接下来,将表单加载到控制器中
$form = $this->getServiceLocator()->get('product_form');
===========================
注意:这在Zend Framework 2.5.2之前一直有效,我整天都在那里。我将尝试看看是否可以将ServiceManagerWareInterface应用到我的实体中,以及这是否符合我的要求,尽管这最终无助于解决我的问题:谢谢你的回答。实际上,我更进一步了,不需要手动填充select语句,因为有DOCTRINENTITY表单元素,但这些元素目前不适用于编辑目的。这种手动方法是有效的,但它缺乏神奇的发生-仍然是一个很好的答案;但问题是,我认为应该是$groupForms[$group->id]=$group->name?有关于ZF2水合器的最新情况吗?我正在实现一个hack,它从一个实体手动构造一个数组,并用setValueOptions设置它。如何将关联实体与选择下拉列表链接?例如:一个用户可以有多个客户端,所以当我编辑一个用户时,我需要一个客户端名称的下拉列表。@hohner只需查看github上DoctrineModule文档文件夹中的文档,Bakura就写了一篇惊人的自述;