我有一個表格(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!
}
}
它的工作原理,但字段集類有兩個依賴於它。我想注入它們。爲了做到這一點,我創建了一個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 \表格\ FormElementManager :: GET無法獲取或創建存儲\表格\字段集\富
我也直接試過這個實例:
'service_manager' => [
'factories' => [
'Storage\Form\Fieldset\Foo' => 'Storage\Form\Fieldset\Factory\FooFieldsetFactory',
],
],
沒有效果,同樣的錯誤。
而且這也沒有工作(同樣的錯誤):
'form_elements' => [
'factories' => [
'Storage\Form\Fieldset\Foo' => 'Storage\Form\Fieldset\Factory\FooFieldsetFactory',
],
],
所以對於一個字段的引用服務似乎不起作用。或者我做錯了什麼?
如何使用表單字段集的服務?
UPDATE
有了一些debuggin我發現,我的Foo
字段集工廠無法找到,因爲它沒有被添加到Zend\Form\FormElementManager
的factories
名單。下面是在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' **,元素只是沒有被找到,例如:'沒有在form中找到[foo]的名字。對於**'FieldSet's **:與以前相同的錯誤:'Zend \ Form \ FormElementManager :: get無法爲Order \ Form \ Fieldset \ Foo獲取或創建一個實例。 – automatix
我還分析了'init()'中'FormElementManager'的狀態。由於'init()'在構造函數之後被調用,所以我期望在MyFieldset-> factory-> formElementManager-> factories'中找到自定義字段集工廠。但該屬性只包含標準的Zend工廠。 – automatix
@automatix您是否使用'formElementManager-> get('Order \ Form \ Fieldset \ Foo')創建* form *;'在'form_elements'中註冊了'Order \ Form \ Fieldset \ Foo'?你的問題只顯示'Storage \ Form \ Fieldset \ Foo'。 – AlexP