通过 Annotation Builder 在 Zend Framework 2 Forms 中填充关系数据
Populating Relationship data in Zend Framework 2 Forms via Annotation Builder
目前,我有文章和标签 tables。我正在尝试将 "Tag" 表单元素自动填充为文章表单上的 select 框。从数据库 table 设置标签 select 框的值选项,然后让文章在 "bind" 方法调用期间自动绑定标签数据的最佳方法是什么?
Article.php
<?php
// Article class
class Article {
/**
*
* @var \Doctrine\Common\Collections\Collection|Tag[]
*
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")
* @Orm\JoinTable(name="rel_article_tag", joinColumns={@ORM\JoinColumn(name="article_id", referencedColumnName="article_id")}, inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="tag_id")})
*
* @Form\Required(false)
* @Form\Type("Zend\Form\Element\Select")
* @Form\Options({"label":"Tags: ")
* @Form\Attributes({"id":"tags", "data-placeholder":"Choose tags...", "multiple" : "multiple", "class" : "chosen-select"})
*/
private $tags;
public function __construct()
{
$this->tags = new ArrayCollection();
}
public function getTags()
{
return $this->tags;
}
public function addTags($tags)
{
$this->tags = $tags;
}
public function removeTags()
{
$this->tags = new ArrayCollection();
}
}
ArticleController.php
class ArticleController{
public function editAction()
{
$builder = new AnnotationBuilder();
$form = $builder->createForm(new TblArticle());
$id = 1;
$article = $em->find('Admin\Entity\TblArticle', $id);
$form->bind($article);
}
}
我做了什么
在 ArticleController::editAction()
中,我已将值选项动态添加到表单上的标签元素。
class ArticleController
{
public function editAction()
{
$builder = new AnnotationBuilder();
$form = $builder->createForm(new TblArticle());
// add tag options to form
$sm = $this->getServiceLocator();
$em = $sm->get('Doctrine\ORM\EntityManager');
$tags = $em->getRepository('Admin\Entity\LuTag')->findAll();
$tagOptions = [null => ''];
foreach ($tags as $tag) {
$tagOptions[$tag->getTagId()] = $tag->getName();
}
$form->get('tags')->setValueOptions($tagOptions);
// end add tag options to form
$id = 1;
$article = $em->find('Admin\Entity\TblArticle', $id);
$form->bind($article);
if ($article->getTags()) {
$tagIds = array();
foreach ($article->getTags() as $tag) {
$tagIds[] = $tag->getTagId();
}
$form->get('tags')->setValue($tagIds);
}
}
}
我的控制器中的代码似乎过多,我知道这是不对的,但我不确定如何更好地做到这一点。可能使用为 Tag 元素设置值选项的 FormBuilder?
谢谢。
基本上您需要在标签实体注释中指定一个存储库 class,如下所示:
@ORM\Entity(repositoryClass="Admin\Entity\LuTag")
然后你可以使用 Doctrines DoctrineModule\Form\Element\ObjectSelect 类型,它将能够提供你请求的功能:
Article.php(注意@Form\Type注释和附加的@Form\Options条目)
...
/**
*
* @var \Doctrine\Common\Collections\Collection|Tag[]
*
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")
* @Orm\JoinTable(name="rel_article_tag", joinColumns={@ORM\JoinColumn(name="article_id", referencedColumnName="article_id")}, inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="tag_id")})
*
* @Form\Required(false)
* @Form\Type("DoctrineModule\Form\Element\ObjectSelect")*
* @Form\Options({"label":"Tags: ", "target_class": "Admin\Entity\LuTag", "property": "name"})
* @Form\Attributes({"id":"tags", "data-placeholder":"Choose tags...", "multiple" : "multiple", "class" : "chosen-select"})
*/
private $tags;
另请查看 https://github.com/doctrine/DoctrineModule/blob/master/docs/form-element.md
有关 ObjectSelect 的更多信息
最后您需要使用
构建您的表单
DoctrineORMModule\Form\Annotation\AnnotationBuilder
而不是 Zends AnnotationBuilder 以解决 object_manager 依赖关系。
/* using the service manager like this within a controller method is
bad practice. Inject the EntityManager using a Controller Factory! */
$sm = $this->getServiceLocator();
$em = $sm->get('Doctrine\ORM\EntityManager');
$builder = new DoctrineORMModule\Form\Annotation\AnnotationBuilder($em);
$form = $builder->createForm(TblArticle::class);
这应该可以解决问题。
目前,我有文章和标签 tables。我正在尝试将 "Tag" 表单元素自动填充为文章表单上的 select 框。从数据库 table 设置标签 select 框的值选项,然后让文章在 "bind" 方法调用期间自动绑定标签数据的最佳方法是什么?
Article.php
<?php
// Article class
class Article {
/**
*
* @var \Doctrine\Common\Collections\Collection|Tag[]
*
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")
* @Orm\JoinTable(name="rel_article_tag", joinColumns={@ORM\JoinColumn(name="article_id", referencedColumnName="article_id")}, inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="tag_id")})
*
* @Form\Required(false)
* @Form\Type("Zend\Form\Element\Select")
* @Form\Options({"label":"Tags: ")
* @Form\Attributes({"id":"tags", "data-placeholder":"Choose tags...", "multiple" : "multiple", "class" : "chosen-select"})
*/
private $tags;
public function __construct()
{
$this->tags = new ArrayCollection();
}
public function getTags()
{
return $this->tags;
}
public function addTags($tags)
{
$this->tags = $tags;
}
public function removeTags()
{
$this->tags = new ArrayCollection();
}
}
ArticleController.php
class ArticleController{
public function editAction()
{
$builder = new AnnotationBuilder();
$form = $builder->createForm(new TblArticle());
$id = 1;
$article = $em->find('Admin\Entity\TblArticle', $id);
$form->bind($article);
}
}
我做了什么
在 ArticleController::editAction()
中,我已将值选项动态添加到表单上的标签元素。
class ArticleController
{
public function editAction()
{
$builder = new AnnotationBuilder();
$form = $builder->createForm(new TblArticle());
// add tag options to form
$sm = $this->getServiceLocator();
$em = $sm->get('Doctrine\ORM\EntityManager');
$tags = $em->getRepository('Admin\Entity\LuTag')->findAll();
$tagOptions = [null => ''];
foreach ($tags as $tag) {
$tagOptions[$tag->getTagId()] = $tag->getName();
}
$form->get('tags')->setValueOptions($tagOptions);
// end add tag options to form
$id = 1;
$article = $em->find('Admin\Entity\TblArticle', $id);
$form->bind($article);
if ($article->getTags()) {
$tagIds = array();
foreach ($article->getTags() as $tag) {
$tagIds[] = $tag->getTagId();
}
$form->get('tags')->setValue($tagIds);
}
}
}
我的控制器中的代码似乎过多,我知道这是不对的,但我不确定如何更好地做到这一点。可能使用为 Tag 元素设置值选项的 FormBuilder?
谢谢。
基本上您需要在标签实体注释中指定一个存储库 class,如下所示:
@ORM\Entity(repositoryClass="Admin\Entity\LuTag")
然后你可以使用 Doctrines DoctrineModule\Form\Element\ObjectSelect 类型,它将能够提供你请求的功能:
Article.php(注意@Form\Type注释和附加的@Form\Options条目)
...
/**
*
* @var \Doctrine\Common\Collections\Collection|Tag[]
*
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")
* @Orm\JoinTable(name="rel_article_tag", joinColumns={@ORM\JoinColumn(name="article_id", referencedColumnName="article_id")}, inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="tag_id")})
*
* @Form\Required(false)
* @Form\Type("DoctrineModule\Form\Element\ObjectSelect")*
* @Form\Options({"label":"Tags: ", "target_class": "Admin\Entity\LuTag", "property": "name"})
* @Form\Attributes({"id":"tags", "data-placeholder":"Choose tags...", "multiple" : "multiple", "class" : "chosen-select"})
*/
private $tags;
另请查看 https://github.com/doctrine/DoctrineModule/blob/master/docs/form-element.md 有关 ObjectSelect 的更多信息
最后您需要使用
构建您的表单DoctrineORMModule\Form\Annotation\AnnotationBuilder
而不是 Zends AnnotationBuilder 以解决 object_manager 依赖关系。
/* using the service manager like this within a controller method is
bad practice. Inject the EntityManager using a Controller Factory! */
$sm = $this->getServiceLocator();
$em = $sm->get('Doctrine\ORM\EntityManager');
$builder = new DoctrineORMModule\Form\Annotation\AnnotationBuilder($em);
$form = $builder->createForm(TblArticle::class);
这应该可以解决问题。