如何在ZF2中的字段集工厂中使用集合 [英] How to use collections in a fieldset factory in ZF2

查看:130
本文介绍了如何在ZF2中的字段集工厂中使用集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个有ZF2和Doctrine的项目。我试图在表单创建中使用Doctrine Hydrator,如本教程。在这种方法中,在控制器中创建一个ObjectManager对象,并在实例化时传递给新表单。当我想使用ZF2的FormElementManager时,将ObjectManager对象从控制器传递给表单会导致问题,因为ZF2要求我通过Zend\Form\FormElementManager获取表单类的实例,而不是直接实例化。为了解决这个要求,我已经根据如何通过ZF2 FormElementManager将Doctrine ObjectManager传递给窗体。该问题的答案中提出的方法适用于典型的fieldset元素,但是我需要确定如何包含一个集合元素。本教程使用父字段集中的集合元素中的ObjectManager对象,我需要找出如何使用工厂添加集合。



TagFieldset从教程中我试图效仿:



 命名空间Application\Form; 

使用Application\Entity\Tag;
使用Doctrine\Common\Persistence\ObjectManager;
使用DoctrineModule\Stdlib\Hydrator\DoctrineObject作为DoctrineHydrator;
使用Zend\Form\Fieldset;
使用Zend\InputFilter\InputFilterProviderInterface;

class TagFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(ObjectManager $ objectManager)
{
parent :: __ construct('tag');

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

$ this-> add(array(
'type'=>'Zend\Form\Element\Hidden',
'name'=> 'id'
));

$ this-> add(array(
'type'=>'Zend\Form\Element\Text',
'name'=> 'name',
'options'=> array(
'label'=>'Tag'

));
}

public function getInputFilterSpecification()
{
return array(
'id'=> array(
'required'= > false
),

'name'=> array(
'required'=> true

);
}
}



新TagFieldsetFactory:



 命名空间Application\Form; 

使用Zend\Form\Fieldset;
使用Application\Entity\Tag;

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

$ fieldset = new Fieldset('tags');
$ fieldset-> setHydrator($ hydrator);
$ fieldset-> setObject(new Tag);

// ...添加字段集元素。
$ fieldset-> add(['...']);
// ...

return $ fieldset;
}
}



我正在尝试模拟的教程中的BlogPostFieldset:



 命名空间Application\Form; 

使用Application\Entity\BlogPost;
使用Doctrine\Common\Persistence\ObjectManager;
使用DoctrineModule\Stdlib\Hydrator\DoctrineObject作为DoctrineHydrator;
使用Zend\Form\Fieldset;
使用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());

$ this-> add(array(
'type'=>'Zend\Form\Element\Text',
'name'=> 'title'
));

$ tagFieldset = new TagFieldset($ objectManager);
$ this-> add(array(
'type'=>'Zend\Form\Element\Collection',
'name'=>'tags'
'options'=>数组(
'count'=> 2,
'target_element'=> $ tagFieldset

));
}

public function getInputFilterSpecification()
{
return array(
'title'=> array(
'required'= > true
),
);
}
}



新BlogPostFieldsetFactory:



 命名空间Application\Form; 

使用Zend\Form\Fieldset;
使用Application\Entity\BlogPost;

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

// ...添加字段集元素。
$ fieldset-> add(['...']);
// ...

return $ fieldset;
}
}



in module.config.php:



 'form_elements'=> [
'工厂'=> [
'UpdateBlogPostForm'=> 'Application\Form\UpdateBlogPostFormFactory',
'BlogPostFieldset'=> 'Application\Form\BlogPostFieldsetFactory',
'TagFieldset'=> 'Application \Form\TagFieldsetFactory',
],
],

当我添加fieldset元素在我的新的BlogPostFieldsetFactory我替换原始字段集中的代码:

  $ this->添加(array(
'type'=>'Zend\Form\Element\Text',
'name'=>'title'
));

与此:

  $ fieldset-> add(array(
'type'=>'Zend\Form\Element\Text',
'name'=>'title '
));

如何从原始字段集中替换集合元素:

  $ tagFieldset = new TagFieldset($ objectManager); 
$ this-> add(array(
'type'=>'Zend\Form\Element\Collection',
'name'=>'tags'
'options'=>数组(
'count'=> 2,
'target_element'=> $ tagFieldset

));


解决方案

也许我得到你的问题错误...但是如果你替换了这个

  $ this-> add(array(
'type'=> Zend\Form\Element\Text',
'name'=>'title'
));

这样:

  $ fieldset-> add(array(
'type'=>'Zend\Form\Element\Text',
'name'=>'title '
));

那么你可能可以替换这个:

  $ tagFieldset = new TagFieldset($ objectManager); 
$ this-> add(array(
'type'=>'Zend\Form\Element\Collection',
'name'=>'tags'
'options'=>数组(
'count'=> 2,
'target_element'=> $ tagFieldset

));

与此:

  $ tagFieldset = new TagFieldset($ objectManager); 
$ fieldset-> add(array(
'type'=>'Zend\Form\Element\Collection',
'name'=>'tags'
'options'=>数组(
'count'=> 2,
'target_element'=> $ tagFieldset

));

现在,如果你不能将$ objectManger传递给窗体...如果你看代码你有这个东西可用$ serviceManager,那东西看起来像一个DI容器,我可以确定你可以从那里得到$ objectManager实例,如果不可用,你可以把它的一个实例放在里面。



所以最终的代码可能结束如下所示:

  $ objectManager = $ serviceManager- > get('DoctrineObjectManager')//或类似的东西
$ tagFieldset = new TagFieldset($ objectManager);
$ fieldset-> add(array(
'type'=>'Zend\Form\Element\Collection',
'name'=>'tags'
'options'=>数组(
'count'=> 2,
'target_element'=> $ tagFieldset

));


I am developing a project with ZF2 and Doctrine. I am attempting to use 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. Passing the ObjectManager object from the controller to the form creates a problem when I want to use ZF2's FormElementManager because ZF2 requires that I get an instance of the form class through the Zend\Form\FormElementManager instead of directly instantiating it. To work around this requirement, I have created form and fieldset factories based upon the answer to the question How to pass a Doctrine ObjectManager to a form through ZF2 FormElementManager. The method presented in the answer to the question works for typical fieldset elements, but I need to determine how to include a collection element. The tutorial uses the ObjectManager object in the collection element in the parent fieldset, and I need to figure out how to add the collection using a factory.

TagFieldset from the tutorial that I am trying to emulate:

namespace Application\Form;

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

class TagFieldset extends Fieldset implements InputFilterProviderInterface
{
    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('tag');

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

        $this->add(array(
            'type' => 'Zend\Form\Element\Hidden',
            'name' => 'id'
        ));

        $this->add(array(
            'type'    => 'Zend\Form\Element\Text',
            'name'    => 'name',
            'options' => array(
                'label' => 'Tag'
            )
        ));
    }

    public function getInputFilterSpecification()
    {
        return array(
            'id' => array(
                'required' => false
            ),

            'name' => array(
                'required' => true
            )
        );
    }
}

new TagFieldsetFactory:

namespace Application\Form;

use Zend\Form\Fieldset;
use Application\Entity\Tag;

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

        $fieldset = new Fieldset('tags');
        $fieldset->setHydrator($hydrator);
        $fieldset->setObject(new Tag);

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

        return $fieldset;
    }
}

BlogPostFieldset from the tutorial that I am trying to emulate:

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

        $this->add(array(
            'type' => 'Zend\Form\Element\Text',
            'name' => 'title'
        ));

        $tagFieldset = new TagFieldset($objectManager);
        $this->add(array(
            'type'    => 'Zend\Form\Element\Collection',
            'name'    => 'tags',
            'options' => array(
                'count'           => 2,
                'target_element' => $tagFieldset
            )
        ));
    }

    public function getInputFilterSpecification()
    {
        return array(
            'title' => array(
                'required' => true
            ),
        );
    }
}

new BlogPostFieldsetFactory:

namespace Application\Form;

use Zend\Form\Fieldset;
use Application\Entity\BlogPost;

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

in module.config.php:

'form_elements' => [
    'factories' => [
        'UpdateBlogPostForm' => 'Application\Form\UpdateBlogPostFormFactory',
        'BlogPostFieldset' => 'Application\Form\BlogPostFieldsetFactory',
        'TagFieldset' => 'Application\Form\TagFieldsetFactory',
    ],
],

When I add the fieldset elements In my new BlogPostFieldsetFactory I replace this code from the original fieldset:

$this->add(array(
        'type' => 'Zend\Form\Element\Text',
        'name' => 'title'
));

with this:

$fieldset->add(array(
        'type' => 'Zend\Form\Element\Text',
        'name' => 'title'
));

How do I replace the collection element from the original fieldset:

$tagFieldset = new TagFieldset($objectManager);
$this->add(array(
        'type'    => 'Zend\Form\Element\Collection',
        'name'    => 'tags',
        'options' => array(
                'count'           => 2,
                'target_element' => $tagFieldset
        )
));

解决方案

maybe i'm getting your question wrong.... but if you replaced this

$this->add(array(
        'type' => 'Zend\Form\Element\Text',
        'name' => 'title'
));

whith this:

$fieldset->add(array(
        'type' => 'Zend\Form\Element\Text',
        'name' => 'title'
));

then you probably can replace this:

$tagFieldset = new TagFieldset($objectManager);
$this->add(array(
        'type'    => 'Zend\Form\Element\Collection',
        'name'    => 'tags',
        'options' => array(
                'count'           => 2,
                'target_element' => $tagFieldset
        )
));

with this:

$tagFieldset = new TagFieldset($objectManager);
$fieldset->add(array(
        'type'    => 'Zend\Form\Element\Collection',
        'name'    => 'tags',
        'options' => array(
                'count'           => 2,
                'target_element' => $tagFieldset
        )
));

now, if you cant pass the $objectManger to the form... well if you look at the code you have this thing available $serviceManager, that thing looks like a DI container, im sure you can get the $objectManager instance from there, and if is not available, you can probably put an instance of it inside.

So de final code probably ending looks like this:

$objectManager =  $serviceManager->get('DoctrineObjectManager') //or something like this
$tagFieldset = new TagFieldset($objectManager);
$fieldset->add(array(
        'type'    => 'Zend\Form\Element\Collection',
        'name'    => 'tags',
        'options' => array(
                'count'           => 2,
                'target_element' => $tagFieldset
        )
));

这篇关于如何在ZF2中的字段集工厂中使用集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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