仅具有多个字段集的 ZF2 表单 getData returns 一个字段集的数据

ZF2 Form getData with multiple fieldsets only returns data for one fieldset

我的表单中有两个字段集。我可以通过在字段集上使用 setUseAsBaseFieldset(true) 来组合字段集,这样我就可以在表单中看到现有数据。当我 post 表单并使用 getData() 时,我只获取一个字段集的数据。

我怀疑这与我添加字段集的方式以及我需要使用 setUseAsBaseFieldset(true) 来补充它们有关。

我的系统有三种类型的帐户 - 客户和其他两种。他们都有一个基本的用户名、密码、角色字段集,名为 customer.

我的代码结构方式:我有一个加载客户字段集的 AccountForm,然后我的控制器添加编辑器字段集。

//AccountForm.php
public function __construct($config = array()) {
    parent::__construct($name = null);

    parent::setAttribute('method', 'post');
    parent::setAttribute('action', $config['action']);


    $this->setHydrator( new ArraySerializable () );

    $this->add(new CustomerFieldset(array('adapter' => $config['adapter'])));

    $this->add(array(
        'name' => 'submit',
        'attributes' => array(
            'type' => 'submit',
            'required' => 'required',
            'value' => 'Submit',
            'class' => 'btn btn-primary',
        )
    ));


}

//CustomerFieldset.php
    public function __construct($config) {
        parent::__construct('user');

        $this->adapter = $config['adapter'];

        $this->setObject(new User())
             ->setHydrator( new ArraySerializable (false));

        $this->setUseAsBaseFieldset(true);
        $this->add(array(
            'name' => 'id',
            'attributes' => array(
                'type' => 'hidden',
            ),
        ));


        $this->add(array(
            'name' => 'email',
            'type' => 'email',
            'attributes' => array(
                'id' => 'email',
                'required' => 'required',
                'class' => 'form-control',
            ),
            'options' => array(
                'label' => 'Email: ',
            ),
        ));
        $this->add(array(
            'name' => 'firstname',
            'type' => 'text',
            'attributes' => array(
                'id' => 'firstname',
                'required' => 'required',
                'class' => 'form-control',
            ),
            'options' => array(
                'label' => 'First Name: ',
            ),
        ));
        $this->add(array(
            'name' => 'lastname',
            'type' => 'text',
            'attributes' => array(
                'id' => 'lastname',
                'required' => 'required',
                'class' => 'form-control',
            ),
            'options' => array(
                'label' => 'Last Name: ',
            ),
        ));

        $this->add(array(
            'name' => 'role_id',
            'type' => 'select',
            'attributes' => array(
                'id' => 'role',
                'required' => 'required',
                'class' => 'form-control',
            ),
            'options' => array(
                'label' => 'Role: ',
                'empty_option' => 'Please select role',
                'value_options' => $this->getDbValues('acl_roles'),
            ),
        ));
        $this->add(array(
            'name' => 'password',
            'type' => 'password',
            'attributes' => array(
                'id' => 'password',
                'class' => 'form-control',
            ),
            'options' => array(
                'label' => 'Password (leave blank to not change): ',
            ),
        ));

        $this->add(array(
            'name'       => 'confirm-password',
            'type'       => 'Password',
            'attributes' => array(
                'id' => 'confirm-password',
                'class' => 'form-control',
            ),
            'options' => array(
                'label' => 'Confirm Password: ',
            ),
        ));

    }

//EditorFieldset.php
public function __construct() {
    parent::__construct('editor');

    $this->setObject(new Editor())
         ->setHydrator( new ArraySerializable (false));

    $this->add(array(
        'name' => 'id',
        'type' => 'hidden',
        'attributes' => array(
            'required' => true,
        ),
    ));
    $this->add(array(
        'name' => 'additional',
        'type' => 'text',
        'attributes' => array(
            'required' => true,
            'class' => 'form-control',
            'id' => 'additional',
        ),
        'options' => array(
            'label' => 'Additional Details: ',
        ),
    ));
    //... more elements
}

//controller
//$form already has customer fieldset. Add editor fieldset.
$form = $this->getForm();
$fieldset = new EditorFieldset();
$fieldset->setUseAsBaseFieldset(true); //set so I can bind to this fieldset
$form->add($fieldset);
/** @var $editor = row object */
$form->bind($editor);

$user = $form->get('user')->setUseAsBaseFieldset(true); //set so later I can bind to this fieldset
$form->remove('user'); //remove fieldset and re-add it with above param set
$form->add($user, array('priority' => 100)); // 100 - high priority - appear at top of form.

$userTable = $this->getServiceLocator()->get('Application\Model\CustomerTable');
$form->bind($userTable->fetchRowById($id));
$request = $this->getRequest();
if($request->isPost()) {
    $form->getInputFilterSpecification();
    $data = $request->getPost();
    $form->setData($data);
    if ($form->isValid()) {
        $validatedData = $form->getData();
        var_dump($validatedData); //debug
    }
 }
 //...view model and other stuff

[编辑]

当我从字段集中删除 setUseAsBaseFieldset(true) 时,我会在使用 getData() 时获得所有值,但是表单不会填充字段。

根据我最后的评论,我已经将我的 setUseAsBaseFieldset(true) 声明包装在光荣的 if 声明中:

if(!$this->getRequest()->isPost()) {
    $fieldset->setUseAsBaseFieldset(true);
}

我认为这不是正确的解决方案。更多是对我创建的问题的 hacky 修复。

也许为时已晚,但值得为将来了解。

$form->getInputFilter()->getValues()

它returns所有过滤后的值。