Создайте выпадающий список в Zend Framework 2

Я знаю, что это звучит намного более основательно, но я хочу опубликовать свой вопрос, поскольку он связан с Zend Framework 2. Я знаю эту форму из модуля примера Zend

namespace Album\Form; use Zend\Form\Form; class AlbumForm extends Form { public function __construct($name = null) { // we want to ignore the name passed parent::__construct('album'); $this->setAttribute('method', 'post'); $this->add(array( 'name' => 'id', 'attributes' => array( 'type' => 'hidden', ), )); $this->add(array( 'name' => 'artist', 'attributes' => array( 'type' => 'text', ), 'options' => array( 'label' => 'Artist', ), )); $this->add(array( 'name' => 'title', 'attributes' => array( 'type' => 'text', ), 'options' => array( 'label' => 'Title', ), )); $this->add(array( 'name' => 'submit', 'attributes' => array( 'type' => 'submit', 'value' => 'Go', 'id' => 'submitbutton', ), )); } } 

И это называется таким образом

 <?php $form = $this->form; $form->setAttribute('action', $this->url('album', array('action' => 'add'))); $form->prepare(); echo $this->form()->openTag($form); echo $this->formHidden($form->get('id')); echo $this->formRow($form->get('title')); echo $this->formRow($form->get('artist')); echo $this->formSubmit($form->get('submit')); echo $this->form()->closeTag(); 

Как добавить раскрывающийся список для поля исполнителя, где список хранится в ассоциативном массиве. Поскольку я попадал в Zend Framework 2, мне нужны предложения от экспертов. Я следовал этой предыдущей статье, но для меня это было несколько непонятно.

Это один из способов сделать это для статических параметров.

 .... $this->add(array( 'type' => 'Zend\Form\Element\Select', 'name' => 'number' 'options' array( 'options' => array( '1' => 'one', '2', 'two' ) ) )); 

Имейте в виду….

Поскольку вы создаете форму внутри конструктора, у вас не будет доступа к ServiceManger. Это может вызвать проблему, если вы хотите заполнить базу данных.

Давайте попробуем что-нибудь вроде …

 class AlbumForm extends Form implements ServiceManagerAwareInterface { public function __construct() { .... $this->add(array( 'type' => 'Zend\Form\Element\Select', 'name' => 'number' )); .... } 

….

 public function initFormOptions() { $this->get('number')->setAttribute('options', $this->getNumberOptions()); } protected function getNumberOptions() { // or however you want to load the data in $mapper = $this->getServiceManager()->get('NumberMapper'); return $mapper->getList(); } public function getServiceManager() { if ( is_null($this->serviceManager) ) { throw new Exception('The ServiceManager has not been set.'); } return $this->serviceManager; } public function setServiceManager(ServiceManager $serviceManager) { $this->serviceManager = $serviceManager; } 

Но это не здорово, переосмыслить …

Расширение формы, чтобы вы могли создать форму, не совсем корректно. Мы не создаем новый тип формы, мы просто создаем форму. Это требует фабрики. Кроме того, преимущества использования фабрики здесь состоят в том, что мы можем настроить ее таким образом, чтобы мы могли использовать диспетчер сервисов для ее обслуживания, таким образом менеджер сервиса может вводить себя, а не делать это вручную с контроллера. Другим преимуществом является то, что мы можем вызывать эту форму всякий раз, когда у нас есть менеджер сервисов.

Еще один момент, который стоит сделать, заключается в том, что там, где это имеет смысл, я думаю, что лучше взять код из контроллера. Контроллер не является дампом сценария, поэтому приятно иметь объекты для себя. То, что я пытаюсь сказать, заключается в том, что полезно вводить объект с объектами, которые ему нужны, но не совсем просто передать данные из контроллера, потому что он создает слишком большую зависимость. Не ложки предметов корма с контроллера, вставьте ложку.

Во всяком случае, слишком много написано больше кода …

 class MySpankingFormService implements FactoryInterface { public function createService(ServiceLocatorInterface $serviceManager ) { $mySpankingNewForm = new Form; // build that form baby, // you have a service manager, // inject it if you need to, // otherwise just use it. return $mySpankingNewForm; } } 

контроллер

 <?php class FooController { ... protected function getForm() { if ( is_null($this->form) ) { $this->form = $this->getServiceManager()->get('MySpankingFormService'); } return $this->form; } ... } 

module.config.php

 ... 'service_manager' => array ( 'factories' => array ( ... 'MySpankingFormService' => 'MyNameSpacing\Foo\MySpankingFormService', ...