2017-06-02 72 views
0

我们使用ZF2工作,但对于我们的最后一个项目,我们决定开始与ZF3。
现在我面临的创作形式的问题。Zend框架3自定义元素

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

我在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' 
    ) 
); 

现在这是不可能了,因为服务定位器被删除,工厂的使用是必要的,但我正在努力寻找如何做同样的事情。

牢记使用的工厂,我想这个配置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。

有谁已经遇到了这个问题,并找到了解决办法?

+0

你得到什么错误?请不要使用闭包作为工厂使用http://zendframework.github.io/zend-servicemanager/migration/#factoryinterface - >闭包不可缓存,并且不像工厂类可重用 – Dymen1

+0

其实,我不是得到一个错误,工厂根本就没有被调用。我100%肯定它,因为我甚至在里面放了一个模子,没有成功的结果。 关闭关闭,我用它们只是为了在这里表示,通常我使用类。 – Matteo

+0

如何将'Car \ Form \ Element \ ManufacturerSelect'添加到您的表单中?仍然使用'$ this-> add(['type'=> class])'? – Dymen1

回答

0

你加入“__construct”功能元素?如果是这样的尝试“初始化”

编辑:

首先你并不需要创建一个自定义选择通过数据库来填充它。只需用工厂创建一个表单,在工厂从数据库获取数据并传递给表单。并使用表单类中的数据作为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。

配置:

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

不要忘记 '的Zend \表' 添加到应用程序配置的 '模块'。

元素:

class CustomElement extends Text 
{ 
} 

元件厂:

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

字段集/表:

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); 
      ); 
     } 
} 
+0

已经尝试过,但没有成功的结果.. – Matteo

+0

等你怎么称呼形式?你必须通过FormElementManager调用窗体来使工厂工作。新的MyForm()在那里不起作用。 –

+0

由于在ZF2中使用它是强制性的,我也在ZF3中使用它。 但是,仍然没有调用元素工厂(但表单工厂) – Matteo