Проход ZF2 к элементу формы

Я создаю форму, которая нуждается в динамических параметрах, основанных на маршрут ценность survey_question_reference

'main-surveyquestions'=> [
'type'    => 'segment',
'options' => [
'route'       => '/survey-questions[/:survey_question_reference][/:answer]',
'constraints' => [
'survey_question_reference' => '[0-9]*',
'answer' => '(answer)',
],
'defaults'    => [
'controller' => 'Main\Controller\Main',
'action'     => 'surveyquestions'
]
]
],

Это Form код, который вызывает FormElement:

/**
* Init
*/
public function init()
{
/**
* Survey Answer
*/
$this->add(
[
'type'       => 'Main\Form\Element\SurveyAnswerRadio',
'name'       => 'survey_answer',
'options'    => [
'label' => 'survey_answer'
],
'attributes' => [
'id' => 'survey_answer'
]
]
);
}

Ниже приведен код из элемента формы. Где я жестко закодировал ‘sqReference’ => ‘1’ 1 должно быть заменено значением survey_question_reference с маршрута.

namespace Main\Form\Element;

use Doctrine\ORM\EntityManager;
use Zend\Form\Element\Radio;

/**
* Class SurveyAnswerRadio
*
* @package Main\Form\Element
*/
class SurveyAnswerRadio extends Radio
{
/**
* @var EntityManager $entityManager
*/
protected $entityManager;

/**
* @param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}

/**
* Get Value Options
*
* @return array
*
* @throws \Exception
*/
public function getValueOptions()
{
$array = [];

$result = $this->entityManager
->getRepository('AMDatabase\Entity\TheVerse\SA')
->findBy(
[
'sqReference' => '1'
],
[
'surveyAnswer' => 'ASC'
]
);

if (is_array($result) && count($result) > '0') {
/**
* @var \AMDatabase\Entity\TheVerse\SA $val
*/
foreach ($result as $val) {
$array[$val->getReference()] = $val->getSurveyAnswer();
}
}

return $array;
}
}

0

Решение

То, что вы ищете, это впрыскивать survey_question_reference параметр вашего FormElement, Вы можете сделать это в соответствии с предложением @ kuldeep.kamboj в его ответах. Но если вы не хотите изменить свой подход и сохранить свой обычай SurveyAnswerRadio элемент, вы должны внести некоторые изменения fiew в вашем коде:

  1. Делать SurveyAnswerRadio инвентарь Zend\ServiceManager\ServiceLocatorAwareInterface чтобы вы могли реализовать setServiceLocator а также getServiceLocator, которые требуются ServiceManager для автоматического добавления локатора службы при создании экземпляра элемента.
  2. Ваша форма должна также реализовать Zend\ServiceManager\ServiceLocatorAwareInterface,
  3. Реализовать getFormElementConfig метод в вашем Module.php,

Давайте посмотрим на код сейчас. У вас будет что-то вроде этого:

SurveyAnswerRadio:

class SurveyAnswerRadio extends Radio implements ServiceLocatorAwareInterface
{
//Add these two methods

public function setServiceLocator(ServiceLocatorInterface $sl)
{
$this->serviceLocator = $sl;
}

public function getServiceLocator()
{
return $this->serviceLocator;
}

public function getValueOptions()
{
$array = [];
$serviceManager = $this->serviceLocator->getServiceLocator();
$em = $serviceManager->get('Doctrine\ORM\EntityManager');
$sqReference = $serviceManager->get('application')->getMvcEvent()
->getRouteMatch()->getParam('survey_question_reference');

$result = $em->getRepository('AMDatabase\Entity\TheVerse\SA')
->findBy(
['sqReference' => $sqReference],
['surveyAnswer' => 'ASC']
);

if (is_array($result) && count($result) > '0') {
foreach ($result as $val) {
$array[$val->getReference()] = $val->getSurveyAnswer();
}
}

return $array;
}
}

Module.php:

Реализовать getFormElementConfig Метод следующим образом. Это позволяет классу ModuleName\Form\Element\SurveyAnswerRadio быть созданным или вызванным с псевдонимом SurveyAnswerRadio,

class Module implements FormElementProviderInterface
{

// other stuff .....

public function getFormElementConfig()
{
return array(
'invokables' => array(
'SurveyAnswerRadio' => 'ModuleName\Form\Element\SurveyAnswerRadio'
)
);
}
}

Никаких изменений в форме не требуется init метод пусть это как есть.

Обратите внимание, что в вашем контроллере вам нужно будет создать Form через FormElementManager :

$formManager = $this->serviceLocator->get('FormElementManager');
$form = $formManager->get('ModuleName\Form\YourForm');

Пожалуйста, смотрите более подробную информацию в документация

Смотрите также это сообщение который объясняет, как управлять зависимостями в рамках пользовательского Select Элемент в форме.

1

Другие решения

Я предложу изменить подход. Во-первых, не пытайтесь расширить Радио Элемент, который не нужен вообще. Вы можете сделать то же самое в своем классе формы. Во-вторых, ваш менеджер сущностей также не работает в классе Radio / Form до тех пор, пока не найдется механизм поиска.

Поэтому я хотел бы предложить решения, как показано ниже.

Сначала зарегистрируйте свой класс формы как фабрику в module.config.php

'form_elements' => array(
'factories' => array(
'Main\Form\YourFormName' => function($sm) {
$form = new Form\YourFormName();
$form->setEntityManager($sm->getServiceLocator()->get('Doctrine\ORM\EntityManager'));
$form->setServiceLocator($sm->getServiceLocator());
return $form;
},
),
),

Затем внедрите entityManager и serviceLocator в свой класс формы.

use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class YourFormName extends Form implements ObjectManagerAwareInterface, ServiceLocatorAwareInterface
{
protected $entityManager;
protected $serviceLocator;

public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}

public function getServiceLocator()
{
return $this->serviceLocator;
}
public function setEntityManager(ObjectManager $entityManager)
{
$this->entityManager = $entityManager;
}

public function getEntityManager()
{
return $this->entityManager;
}

Затем в методе init у вас serviceLocator / entityManager уже инициализирован.

public function init()
{
$routeMatch = $this->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch();

$array = [];

$result = $this->entityManager
->getRepository('AMDatabase\Entity\TheVerse\SA')
->findBy(
[
'sqReference' => $routeMatch->getParam('survey_question_reference')
],
[
'surveyAnswer' => 'ASC'
]
);

if (is_array($result) && count($result) > '0') {
/**
* @var \AMDatabase\Entity\TheVerse\SA $val
*/
foreach ($result as $val) {
$array[$val->getReference()] = $val->getSurveyAnswer();
}
}

$this->add(
[
'type'       => 'Zend\Form\Element\Radio',
'name'       => 'survey_answer',
'options'    => [
'label' => 'survey_answer',
'value_options' => $array,
],
'attributes' => [
'id' => 'survey_answer',

]
]
);
1

По вопросам рекламы [email protected]