2015-04-10 1 views
0

Я создаю форму, которая нуждается в динамические параметры на основе маршрута значение из survey_question_referenceZF2 Передача Маршрут к элементу формы

'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' необходимо заменить на значение 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; 
    } 
} 

ответ

1

Я предложу изменить подход. Во-первых, не пытайтесь расширить Radio Element, который не нужен вообще. Вы можете сделать то же самое в своем классе формы. Во-вторых, ваш менеджер объектов также не работает в классе 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', 

     ] 
    ] 
);   
+0

'$ routeMatch-> getParam ('survey_question_reference')' not '$ routeMatch-> getParam ('answer')', он сказал, что «нужно заменить значением« survey_question_reference »с маршрута_». – blackbishop

+0

Да, моя ошибка, изменилась. –

1

Что вы looknig для является Inject: параметр к вашему FormElementsurvey_question_reference. Вы можете сделать это, как было предложено @ 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' 
     ) 
    ); 
} 
} 

нет необходимости в методе Form init изменения пусть как есть.

Обратите внимание, что в контроллере, вам придется создавать экземпляры Form через FormElementManager:

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

Пожалуйста, подробнее см в documentation

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

Смежные вопросы