在Zend Framework 2中创建自定义表单元素时,为什么不使用短名称?

时间:2013-04-08 22:47:22

标签: zend-framework zend-framework2

我在这里创建自定义元素:ZF2Docs: Advanced use of Forms

1.在Application / Form / Element / CustomElement.php

中创建CustomElement类

2.添加到我的Module.php函数

public function getFormElementConfig()
{
    return array(
        'invokables' => array(
            'custom' => 'Application\Form\Element\CustomElement',
        ),
    );
}

如果我使用FQCN,它可以正常工作:

$form->add(array(
    'type' => 'Application\Form\Element\CustomElement',
    'name' => 'myCustomElement'
));

但如果我使用短名称:

$form->add(array(
    'type' => 'Custom',
    'name' => 'myCustomElement'
));

抛出异常:

Zend\ServiceManager\ServiceManager::get was unable to fetch or create 
an instance for Custom

1 个答案:

答案 0 :(得分:4)

问题

错误可能是由于您如何实例化$form对象。如果您只是使用new Zend\Form\Form表达式或类似的东西,则不会使用正确的服务定位器设置表单。

$form = new \Zend\Form\Form;
$form->add(array(
    'type' => 'custom',
    'name' => 'foobar',
));

解决方案

这里的技巧是使用FormElementManager服务定位器来实例化表单。

// inside a controller action
$form = $this->getServiceLocator()->get('FormElementManager')->get('Form');
$form->add(array(
    'type' => 'custom',
    'name' => 'foobar',
));

更好的是,在控制器中定义一个form()方法作为为您执行此操作的快捷方式:

class MyController extends AbstractActionController
{
    public function form($name, $options = array())
    {
        $forms = $this->getServiceLocator()->get('FormElementManager');
        return $forms->get($name, $options);
    }

    public function createAction()
    {
        $form = $this->form('SomeForm');
        // ...
    }
}

解释

每个表单对象都附加到表单工厂,表单工厂又连接到服务定位器。此服务定位器负责获取用于实例化新表单/元素/字段集对象的所有类。

如果实例化一个新的表单对象(全部都是自身),则会实例化一个空白服务定位器并用于获取该表单中的后续类。但是每个后续对象都会附加到同一个服务定位器。

这里的问题是getFormElementConfig配置了此服务定位器的一个非常具体的实例。这是FormElementManager服务定位器。一旦配置完毕,从该服务定位器中提取的所有表单都将附加到此服务定位器,并将用于获取其他元素/字段集等。

希望这能解决您的问题。