如何通过ZF2 FormElementManager将Doctrine ObjectManager传递给窗体 [英] How to pass a Doctrine ObjectManager to a form through ZF2 FormElementManager

查看:97
本文介绍了如何通过ZF2 FormElementManager将Doctrine ObjectManager传递给窗体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在ZF2中创建自定义表单元素,这需要FormElementManager。我目前正在使用Doctrine Hydrator创建表单,如本教程。在这种方法中,在控制器中创建一个ObjectManager对象,并在实例化时传递给新表单:

I would like to create custom form elements in ZF2, which requires FormElementManager. I am currently using Doctrine Hydrator in the form creation as shown in this tutorial. In this method, an ObjectManager object is created in the controller and passed to the new form when it is instantiated:

public function editAction()
{
    // Get your ObjectManager from the ServiceManager
    $objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');

    // Create the form and inject the ObjectManager
    $form = new UpdateBlogPostForm($objectManager);

    // …



更新表单:



the update form:

namespace Application\Form;

use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Form;

class UpdateBlogPostForm extends Form
{
    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('update-blog-post-form');

        // The form will hydrate an object of type "BlogPost"
        $this->setHydrator(new DoctrineHydrator($objectManager));

        // Add the user fieldset, and set it as the base fieldset
        $blogPostFieldset = new BlogPostFieldset($objectManager);
        $blogPostFieldset->setUseAsBaseFieldset(true);
        $this->add($blogPostFieldset);

        // … add CSRF and submit elements …

        // Optionally set your validation group here
    }
}



BlogPost字段集:



the BlogPost fieldset:

namespace Application\Form;

use Application\Entity\BlogPost;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;

class BlogPostFieldset extends Fieldset implements InputFilterProviderInterface
{
    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('blog-post');

        $this->setHydrator(new DoctrineHydrator($objectManager))
             ->setObject(new BlogPost());

        // … add fieldset elements …

    }

    // … public function getInputFilterSpecification() …

}

不幸的是,为了使用ZF2的FormElementManager,第二次捕获是你不能直接实例化你的表单类,而是通过Zend\Form\FormElementManager获取一个实例;所以我必须得到这样的形式:

Unfortunately, in order to use ZF2's FormElementManager, the ZF2 manual says, "The second catch is that you must not directly instantiate your form class, but rather get an instance of it through the Zend\Form\FormElementManager;" so I have to get the form like this:

 public function editAction()
 {
     $sl = $this->getServiceLocator();
     $form = $sl->get('FormElementManager')->get('\Application\Form\UpdateBlogPostForm');

有没有办法传递ObjectManager对象 $ objectManager 通过 FormElementManager 的表单,或者是否有一种方法来创建表单中的对象,以便hydrator和fieldset可以使用它?

Is there a way to pass the ObjectManager object $objectManager to the form through FormElementManager, or is there a way to create the object within the form so the hydrator and the fieldset can use it?

推荐答案

DoctrineEntityHydratorFactory



创建hydrator并注入对象管理器的工厂。 >

DoctrineEntityHydratorFactory

A factory that creates the hydrator and injects the object manager.

namespace MyModule\Stdlib\Hydrator;

use DoctrineORMModule\Stdlib\Hydrator\DoctrineEntity;

class DoctrineEntityHydratorFactory
{
    public function __invoke($hydratorPluginManager, $name, $requestedName)
    {
        $serviceManager = $hydratorPluginManager->getServiceLocator();
        $objectManager  = $serviceManager->get('Doctrine\ORM\EntityManager');

        return new DoctrineEntity($objectManager);
    }
}



BlogPostFieldset



一个可重用的字段集,其中包含博客文章的所有元素,并使用 EntityHydrator 来合并 BlogPost 实体。

namespace MyModule\Form;

use Zend\Form\Fieldset;

class BlogPostFieldsetFactory
{
    public function __invoke($formElementManager, $name, $requestedName)
    {
        $serviceManager = $formElementManager->getServiceLocator();
        $hydrator = $serviceManager->get('HydratorManager')->get('DoctrineEntityHydrator');

        $fieldset = new Fieldset('blog_post');
        $fieldset->setHydrator($hydrator);
        $fieldset->setObject(new BlogPost);

        //... add fieldset elements.
        $fieldset->add(['...']);
        //...

        return $fieldset;
    }
}



UpdateBlogPostFormFactory



一个工厂创建博客更新表单。这将附加字段集并设置 use_as_base_fieldset 选项,允许它使用fieldsets hydrator

UpdateBlogPostFormFactory

A factory to create the blog post update form. This attaches the fieldset and sets the use_as_base_fieldset option which allows it to use the fieldsets hydrator.

namespace MyModule\Form;

class UpdateBlogPostFormFactory
{
    public function __invoke($formElementManager, $name, $requestedName)
    {
        $form = new Form('update_blog_post);

        //...
        $factory = new \Zend\Form\Factory($formElementManager);
        $form->setFormFactory($factory);
        $form->add([
            'name' => 'blog_post',
            'type' => 'BlogPostFieldset',
            'options' => [
                'use_as_base_fieldset' => true,   
            ]
        ]);
        //...

        return $form;
    }
}

您还需要注册所需的服务 module.config.php 中的管理员。

You will also need to register the services with the required managers in module.config.php.

return [
    'form_elements' => [
        'factories' => [
            'UpdateBlogPostForm' => 'MyModule\Form\UpdateBlogPostFormFactory',
            'BlogPostFieldset' => 'MyModule\Form\BlogPostFieldsetFactory',
        ],
    ],
    'hydrators' => [
        'factories' => [
            'DoctrineEntityHydrator' => 'MyModule\Stdlib\Hydrator\DoctrineEntityHydratorFactory',
        ],
    ],
];

所以上面你可以在控制器中请求你的表单。

So with the above you can request your form in the controller.

$form = $formElementManager->get('UpdateBlogPostForm');

这篇关于如何通过ZF2 FormElementManager将Doctrine ObjectManager传递给窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆