php - 通过 Annotation Builder 在 Zend Framework 2 Forms 中填充关系数据

标签 php doctrine-orm zend-framework2 zend-form zend-form-element

目前,我有文章和标签表。我正在尝试将“标签”表单元素自动填充为文章表单上的选择框。从数据库表中设置标签选择框的值选项,然后让文章在“绑定(bind)”方法调用期间自动绑定(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);
        }
    }
}

这似乎是我的 Controller 中的代码过多,我知道这是不对的,但我不知道如何更好地做到这一点。可能使用 FormBuilder 来设置 Tag 元素的值选项?

谢谢。

最佳答案

查看本教程:https://samsonasik.wordpress.com/2014/05/22/zend-framework-2-using-doctrinemoduleformelementobjectselect-and-custom-repository/

基本上,您需要在标记实体实体注释中指定存储库类,如下所示:

@ORM\Entity(repositoryClass="Admin\Entity\LuTag")

然后您可以使用 Doctrines DoctrineModule\Form\Element\ObjectSelect Type 它将能够提供您请求的功能:

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);

这应该可以解决问题。

关于php - 通过 Annotation Builder 在 Zend Framework 2 Forms 中填充关系数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34320953/

相关文章:

symfony - 手动生成学说 slug

symfony - 更新后刷新缓慢(Doctrine ORM + Symfony 2)

php - 从 php 生成 xml 和 xsl

javascript - 具有共享 session 和用户身份验证的 WebSockets 和 HTTP 安全性

mysql - 创建查询,当条件为真时添加两个值或仅获取一个值

php - 如何使用骨架项目 'Application' 模块中的错误处理程序来捕获事件回调中的错误?

zend-framework2 - 使用 tableGateway 返回表主键名称

php - 在 Zend Framework 2 中合并输入过滤器

php - Postgresql 更新唯一列并在更新前验证

php - 有什么方法可以用 Laravel 检测数据库表是否存在