У меня есть форма (Zend\Form\Form
) с некоторыми вложенными полями (Zend\Form\Fieldset
). Конструкция довольно похожа на конструкцию в Form Collections tutorial.Как использовать службы для набора полей формы в Zend Framework 2?
Storage\Form\MyForm
|_'Storage\Form\Fieldset\FooFieldset'
|_'Storage\Form\Fieldset\BarFieldset'
|_'Storage\Form\Fieldset\BazFieldset'
...
MyForm
class MyForm {
public function __construct()
{
...
$this->add(
[
'type' => 'Storage\Form\Fieldset\FooFieldset',
'options' => [
'use_as_base_fieldset' => true
]
]
);
}
}
FooFieldset
class FooFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct()
{
parent::__construct('foo');
$this->setHydrator(new ClassMethodsHydrator())->setObject(new Foo()); // dependencies!
}
}
Он работает, но класс FIELDSET имеет два зависимостей в нем. Я хочу их вводить. Для того, чтобы сделать это, я создал FooFieldsetFactory
и расширил /module/MyModule/config/module.config.php
по:
'service_manager' => [
'factories' => [
'Storage\Form\Fieldset\FooFieldset' => 'Storage\Form\Fieldset\Factory\FooFieldsetFactory',
],
],
на заводе просто игнорируются. Я предполагаю, что локатор службы сначала пытается найти класс по пространству имен, и только если ничего не найдено, он смотрит в invokables
и factories
. ОК. Затем я создал псевдоним:
'service_manager' => [
'factories' => [
'Storage\Form\Fieldset\FooFieldset' => 'Storage\Form\Fieldset\Factory\FooFieldsetFactory',
],
],
'aliases' => [
'Storage\Form\Fieldset\Foo' => 'Storage\Form\Fieldset\FooFieldset',
],
... и пытался использовать его вместо Storage\Form\Fieldset\FooFieldset
в моем классе формы. Но теперь я получаю исключение:
Zend \ Form \ FormElementManager :: прибудете не удалось извлечь или создать экземпляр для хранения \ Form \ Fieldset \ Foo
Я также попытался это напрямую :
'service_manager' => [
'factories' => [
'Storage\Form\Fieldset\Foo' => 'Storage\Form\Fieldset\Factory\FooFieldsetFactory',
],
],
Отсутствие эффекта, та же ошибка.
И это тоже не работает (та же ошибка):
'form_elements' => [
'factories' => [
'Storage\Form\Fieldset\Foo' => 'Storage\Form\Fieldset\Factory\FooFieldsetFactory',
],
],
Так ссылается сервис для FIELDSET, кажется, не работает. Или я делаю что-то неправильно?
Как пользоваться услугами для полей форм?
UPDATE
С некоторыми debuggin я узнал, что мой Foo
FIELDSET завод не может быть найден, потому что он не добавляется в factories
списке Zend\Form\FormElementManager
. Вот это место, в Zend\Form\Factory
:
Так что мой конфиг
'form_elements' => [
'factories' => [
'Storage\Form\Fieldset\Foo' => 'Storage\Form\Fieldset\Factory\FooFieldsetFactory',
],
],
игнорируется. Как это исправить?
UPDATE Дополнительная информация, как я создаю мой Form
объект.
/module/Foo/config/module.config.php
return [
'controllers' => [
'factories' => [
'Foo\Controller\My' => 'Foo\Controller\Factory\MyControllerFactory'
]
],
'service_manager' => [
'factories' => [
'Foo\Form\MyForm' => 'Foo\Form\Factory\MyFormFactory',
],
],
];
/module/Foo/src/Foo/Form/Factory/MyFormFactory.php
namespace Foo\Form\Factory;
use ...;
class MyFormFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$form = new MyForm();
$form->setAttribute('method', 'post')
->setHydrator(new ClassMethods())
->setInputFilter(new InputFilter());
return $form;
}
}
/module/Foo/src/Foo/Controller/Factory/MyControllerFactory.php
namespace Foo\Controller\Factory;
use ...;
class MyControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$fooPrototype = new Foo();
$realServiceLocator = $serviceLocator->getServiceLocator();
// $myForm = $realServiceLocator->get('Foo\Form\MyForm'); <-- This doesn't work correctly for this case. The FormElementManager should be used instead.
$formElementManager = $realServiceLocator->get('FormElementManager');
$myForm = $formElementManager->get('Foo\Form\MyForm');
return new MyController($myForm, $fooPrototype);
}
}
Благодарим вас за подробный ответ! Я переместил логику инициализации из конструктора в 'init()'. Но это не работает. Для ** 'Form' ** элементы просто не найдены, например .:' Нет элемента по имени [foo], найденного в форме'. Для ** 'FieldSet's **: та же ошибка, что и раньше:' Zend \ Form \ FormElementManager :: get не удалось получить или создать экземпляр для Order \ Form \ Fieldset \ Foo'. – automatix
Я также проанализировал состояние 'FormElementManager' в' init() '. Поскольку 'init()' вызывается после конструктора, я ожидал, что найду свои собственные фабрики полей в 'MyFieldset-> factory-> formElementManager-> factory'. Но свойство содержит только стандартные фабрики Zend. – automatix
@automatix Вы создаете * форму *, используя '$ formElementManager-> get ('Order \ Form \ Fieldset \ Foo');' с 'Order \ Form \ Fieldset \ Foo' зарегистрированным в' form_elements'? Вы задаете вопрос только: «Хранение \ Форма \ Полеset \ Foo». – AlexP