我知道这个话题是在 2 年前讨论过的。但我坚持我想解决的困难。
我想创建一个包含两个以上选择元素的 zf3 表单。
我想用来自不同存储库的数据填充它们(每个 Select 项目的选项值来自不同的存储库)。
首先,我尝试在表单的构造函数中传递服务管理器(我可以从那里访问我的存储库),但我听说这个解决方案根本不合适。
那么如何在我的表单中包含多个存储库来填充我的选择元素?
我知道这个话题是在 2 年前讨论过的。但我坚持我想解决的困难。
我想创建一个包含两个以上选择元素的 zf3 表单。
我想用来自不同存储库的数据填充它们(每个 Select 项目的选项值来自不同的存储库)。
首先,我尝试在表单的构造函数中传递服务管理器(我可以从那里访问我的存储库),但我听说这个解决方案根本不合适。
那么如何在我的表单中包含多个存储库来填充我的选择元素?
Select
module.config.php
)type
您的表单元素Select
,例如BrandSelect
namespace MyModule\Form\Element;
use Laminas\Form\Element\Select;
class BrandSelect extends Select {
protected $repository;
public function __construct($repository, $name = null, $options = []) {
parent::__construct($name, $options);
$this->repository = $repository;
}
/**
* Initialize the element
*
* @return void
*/
public function init() {
$valueOptions = [];
foreach ($this->repository->fetchBrands() as $brand) {
$valueOptions[$brand->getBrandId()] = $brand->getName();
}
asort($valueOptions);
$this->setValueOptions($valueOptions);
}
}
namespace MyModule\Form\Element;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Interop\Container\ContainerInterface;
use MyModule\Db\Repository;
class BrandSelectFactory implements FactoryInterface {
public function __invoke(ContainerInterface $container, $requestedName, $options = null): BrandSelect {
$repository = $container->get(Repository::class);
return new BrandSelect($repository);
}
}
module.config.php
)namespace MyModule;
return [
// ..
// Other configs
// ..
'form_elements' => [
'factories' => [
Form\Element\BrandSelect::class => Form\Element\BrandSelectFactory::class
]
]
];
type
用于您的表单元素。init()
方法中添加所有元素非常重要,否则将无法正常工作。我还添加了InputFilterProviderInterface
. module.config.php
配置中添加表单工厂,始终在form_elements
键下(就像 对 一样BrandSelect
):namespace MyModule\Form;
use Laminas\Form\Form;
use Laminas\InputFilter\InputFilterProviderInterface;
class BrandForm extends Form implements InputFilterProviderInterface {
public function __construct($name = null, $options = []) {
parent::__construct($name, $options);
}
// IT IS REALLY IMPORTANT TO ADD ELEMENTS IN INIT METHOD!
public function init() {
parent::init();
$this->add([
'name' => 'brand_id',
'type' => Element\BrandSelect::class,
'options' => [
'label' => 'Brands',
]
]);
}
public function getInputFilterSpecification() {
$inputFilter[] = [
'name' => 'brand_id',
'required' => true,
'filters' => [
['name' => 'Int']
]
];
return $inputFilter;
}
}
service manager
,而是FormElementManager
. BrandController
:<?php
namespace MyModule\Controller;
use Laminas\Form\FormElementManager;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;
class BrandController extends AbstractActionController {
private $formManager;
public function __construct(FormElementManager $formManager) {
$this->formManager = $formManager;
}
public function addBrandAction() {
$form = $this->formManager->get(\MyModule\Form\BrandForm::class);
// Do stuff
return new ViewModel([
'form' => $form
]);
}
}
namespace MyModule\Controller;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Interop\Container\ContainerInterface;
class BrandControllerFactory implements FactoryInterface {
public function __invoke(ContainerInterface $container, $requestedName, $options = null): BrandController {
$formManager = $container->get('FormElementManager');
return new BrandController($formManager);
}
}
必须在controllers
key in下配置module.config.php
:
namespace MyModule;
return [
// ..
// Other configs
// ..
'controllers' => [
'factories' => [
Controller\BrandController::class => Controller\BrandControllerFactory::class
],
],
'form_elements' => [
'factories' => [
Form\Element\BrandSelect::class => Form\Element\BrandSelectFactory::class
]
]
];