与工厂一起形成自定义元素

问题描述 投票:0回答:1

我们曾经使用ZF2,但是在上一个项目中,我们决定从ZF3开始。现在我在表单创建中遇到了一个问题。

我想做的是创建一个自定义选择,其中填充了从数据库中检索到的值。

我在ZF2中所做的工作是使用ServiceLocatorAwareInterface创建一个扩展选择的类,例如:

class ManufacturerSelect extends Select implements ServiceLocatorAwareInterface {

    public function init() {
        $manufacturerTable = $this->getServiceLocator()->get('Car\Model\ManufacturerTable');
        $valueOptions = [];
        foreach ($manufacturerTable->fetchAll() as $manufacturer) {
            $valueOptions[$manufacturer->getManufacturerId()] = $manufacturer->getName();
        }
        $this->setValueOptions($valueOptions);
    }

    public function getServiceLocator() {
        return $this->serviceLocator;
    }

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
        $this->serviceLocator = $serviceLocator;
    }

}

然后,以某种形式使用它,足以给出全名

$this->add(
    array(
        'name' => 'manufacturer_id',
        'type' => 'Car\Form\Element\ManufacturerSelect'
    )
);

Now这不可能了,因为已删除了服务定位符,并且有必要使用工厂,但是我一直在努力寻找如何做同样的事情。

记住使用工厂,我在module.config.php中尝试了此配置:

'form_elements' => [
    'factories' => [
        'Car\Form\Element\ManufacturerSelect' => function ($services) {
            $manufacturerTable = $services->get('Car\Model\ManufacturerTable');
            return new ManufacturerSelect($manufacturerTable);
        },
        'Car\Form\CarForm' => function ($services) {
            $manufacturerTable = $services->get('Car\Model\ManufacturerTable');
            return new CarForm($manufacturerTable, 'car-form');
        }
    ]
]

结果:始终调用CarForm的工厂,但不调用ManufacturerSelect的工厂。

一个简单的解决方案是直接在表单类中填充选择,但是我更喜欢使用工厂作为元素,并在需要的任何地方重用它,就像我在ZF2中所做的那样。

是否有人已经遇到此问题并找到了解决方案?

php zend-framework3
1个回答
0
投票

编辑:

首先,您不需要创建自定义选择即可通过数据库进行填充。只需使用工厂创建一个表单,在工厂中从db获取数据并传递给表单即可。并使用表单类中的数据作为select的值选项。

$this-add([ 'type' => Element\Select:.class, 'name' => 'select-element' 'options' => [ 'label' => 'The Select', 'empty_option' => 'Please choose one', 'value_options' => $this-dataFromDB ] ]);

如果您将表单创建为:

new MyForm();

表单元素管理器不会触发自定义元素的工厂。但是;

$container->get('FormElementManager')->get(MyForm::class);

触发自定义元素的工厂。这是一个工作示例。它正在ZF3上运行。

Config:

return [ 'controllers' => [ 'factories' => [ MyController::class => MyControllerFactory::class ] ], 'form_elements' => [ 'factories' => [ CustomElement::class => CustomElementFactory::class, MyForm::class => MyFormFactory::class, ] ] ];

不要忘记将“ Zend \ Form”添加到应用程序配置的“模块”。

Element:

class CustomElement extends Text { }

元素工厂:

class CustomElementFactory implements FactoryInterface { public function __invoke(ContainerInterface $container, $requestedName, array $options = null) { echo 'element factory triggered'; return new CustomElement(); } }

Fieldset / Form:

class MyForm extends Form { public function init() { $this ->add([ 'type' => CustomElement::class, 'name' => 'name', 'options' => [ 'label' => 'label', ], ]) ; } }

字段集/表单工厂:

class MyFormFactory implements FactoryInterface { public function __invoke(ContainerInterface $container, $requestedName, array $options = null) { echo 'form factory triggered'; return new MyForm(); } }

控制器的工厂:

class MyControllerFactory implements FactoryInterface { public function __invoke(ContainerInterface $container, $requestedName, array $options = null) { echo 'controller factory triggered'; return new MyController( $container->get('FormElementManager')->get(MyForm::class); ); } }

© www.soinside.com 2019 - 2024. All rights reserved.