我想利用工厂创建的字段集在Zend Framework 2中创建一个表单,但是我遇到了将字段集与表单连接的问题。
字段集的创建方式如下:
<?php
// File: module/FormElements/src/Form/PersonalDataFieldset.php
namespace FormElements\Form;
use Zend\Form\Factory;
class PersonalDataFieldset extends Factory
{
public function __construct()
{
$factory = new Factory();
$form = $factory->createForm(array(
'fieldsets' => array(
array(
'spec' => array(
'name' => 'data',
'options' => array(
'label' => 'Fieldset Test',
),
'elements' => array(
array(
'spec' => array(
'name' => 'fname',
'type' => 'text',
),
),
array(
'spec' => array(
'name' => 'lname',
'type' => 'text',
),
),
array(
'spec' => array(
'name' => 'email',
'type' => 'email',
),
),
),
),
),
),
));
}
}
表格:
<?php
// File: module/FormElements/src/Form/PersonalDataForm.php
namespace FormElements\Form;
use Zend\Form\Form;
class PersonalDataForm extends Form
{
public function __construct()
{
parent::__construct();
// Field not contained in the fieldset - this works
$this->add(array(
'name'=> 'some-name',
'type' => 'text',
'options' => array(
'label' => 'Test Label',
),
));
// Here I am trying to add the fieldset – this does not work
$this->add(array(
'name' => 'some-other-name',
'type' => 'FormElements\Form\PersonalDataFieldset',
));
}
}
应该连接两者的控制器:
<?php
// File: module/FormElements/src/Controller/FormElementsController.php
namespace FormElements\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use FormElements\Form\PersonalDataForm;
class FormElementsController extends AbstractActionController
{
public function indexAction()
{
$form = new PersonalDataForm();
return new ViewModel(array(
'form' => $form
));
}
}
根据我的尝试,结果会因空视图或异常而异。
例如,根据上面发布的代码,我得到Plugin of type FormElements\Form\PersonalDataFieldset is invalid; must implement Zend\Form\ElementInterface
当然我可以实现接口,因为异常告诉我这样做,但我想了解我在做什么,但我不知道为什么需要这个接口?
createForm
,但也有createFieldset
- 正确的方法是什么?另外,为什么不需要扩展Zend\Form\Fieldset
?答案 0 :(得分:2)
我会避免在你的控制器中调用$form = new PersonalDataForm();
。
我会在工厂中注入该依赖项,该工厂应该可以访问“FormElementManager”
FormElementManager是一个AbstractPluginManager,可以存储所有与表单相关的服务,包括元素,字段集和完整表单(因为它们都扩展了Zend \ Form \ Element)
通过从插件管理器调用表单服务(并确保将该插件管理器注入任何后续表单工厂),您将不会遇到这些“无效插件”错误。
“无效插件”异常通常意味着两件事之一。您没有使用插件管理器注册您的元素,或者您没有在需要的地方正确注入插件管理器。
答案 1 :(得分:1)
移动字段和字段集,将方法从__construct()
添加到init()
方法,然后使用FormElementManager获取表单。它的工作方式与此处所述的zf2 docs
编辑1:我修复了链接,似乎#符号已经正确编码
编辑2:这是ZF2文档部分的引用:
...自定义元素的示例代码...
现在是第一个问题。
如果要通过扩展Zend \ Form \ Form来创建表单类,则不能在__construct中添加自定义元素 - 或者(正如我们在上一个使用自定义元素的FQCN的示例中所做的那样),而是在init()方法中:
namespace Application\Form;
use Zend\Form\Form;
class MyForm extends Form
{
public function init()
{
$this->add(array(
'name' => 'phone',
'type' => 'Phone',
));
}
}
第二个问题是你不能直接实例化你的表单类,而是通过Zend \ Form \ FormElementManager获取它的实例:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
class IndexController extends AbstractActionController
{
public function indexAction()
{
$sl = $this->getServiceLocator();
$form = $sl->get('FormElementManager')->get('\Application\Form\MyForm');
return array('form' => $form);
}
}
最大的好处是,如果它们不符合您的需要,您可以轻松覆盖任何内置的Zend Framework表单元素。例如,如果要创建自己的Email元素而不是标准的元素,则可以简单地创建元素并将其添加到表单元素config,其中键与要替换的元素相同 ...