[英]How to use collections in a fieldset factory in ZF2
我正在用ZF2和Doctrine開發一個項目。 我試圖在表單創建中使用Doctrine Hydrator,如本教程所示。 在此方法中,在控制器中創建ObjectManager對象,並在實例化時將其傳遞給新表單。 當我想使用ZF2的FormElementManager時,將ObjectManager對象從控制器傳遞到表單會產生問題,因為ZF2要求我通過Zend \\ Form \\ FormElementManager獲取表單類的實例,而不是直接實例化它。 為了解決這個問題,我已經基於如何通過ZF2 FormElementManager將Doctrine ObjectManager傳遞給表單的問題的答案創建了表單和字段集工廠 。 該問題的答案中提供的方法適用於典型的fieldset元素,但我需要確定如何包含集合元素。 本教程使用父字段集中的collection元素中的ObjectManager對象,我需要弄清楚如何使用工廠添加集合。
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
)
);
}
}
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;
}
}
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
),
);
}
}
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;
}
}
'form_elements' => [
'factories' => [
'UpdateBlogPostForm' => 'Application\Form\UpdateBlogPostFormFactory',
'BlogPostFieldset' => 'Application\Form\BlogPostFieldsetFactory',
'TagFieldset' => 'Application\Form\TagFieldsetFactory',
],
],
當我添加fieldset元素在我的新BlogPostFieldsetFactory中,我從原始字段集中替換此代碼:
$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' => array(
'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' => array(
'count' => 2,
'target_element' => $tagFieldset
)
));
有了這個:
$tagFieldset = new TagFieldset($objectManager);
$fieldset->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'tags',
'options' => array(
'count' => 2,
'target_element' => $tagFieldset
)
));
現在,如果你不能將$ objectManger傳遞給表單......好吧,如果你查看代碼,你有這個東西可用$ serviceManager,那東西看起來像一個DI容器,我確定你可以從那里得到$ objectManager實例,如果不可用,你可以在里面放一個實例。
所以de final代碼可能結束如下:
$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
)
));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.