ZF2:预填充字段集数据

时间:2013-08-06 07:12:04

标签: data-binding zend-framework2 fieldset

我在Zend Framework 2中遇到了我的字段集问题。 用户可以在表单上保存他的个人数据。如果他已经保存了这个,他们应该预先填入数据库中的数据。这很好,因为它只是一个表单,但我需要一个字段集中的地址数据,以便我可以在我的程序的其他部分使用它。现在输入字段保持为空。

一开始,我会在会话中填写个人数据。我的数据如下:

object(Application\Model\Product\PersonalData)#247 (3) { 
    ["tel":protected]=> string(0) "" 
    ["birthday":protected]=> string(10) "2013-01-01" 
    ["address":protected]=> object(Application\Model\Account\Addresses)#248 (15) {    
        ["firstname":protected]=> string(5) "Ernie" 
        ["surname":protected]=> string(6) "Muppet"    
        ...
    } 
} 

如您所见,数据已绑定到给定对象,PersonalData作为main,以及字段集的Addresses。这似乎工作。 然后我把它放在我的表格中:

$oForm->setData($oForm->getHydrator()->extract($_SESSION->getPersonalData()));
return new ViewModel(array('form'=>$oForm));

addressFieldset有一个保护器和一个绑定,它可以正常工作,因为所有对象都被完美填充。唯一的问题是,当我打开页面时,输入字段为空,只有生日和电话被填充,这些都直接在表格上

我的表单实现了这样的地址字段集:

$addressFieldset = new AddressFieldset($lang);
$addressFieldset->setUseAsBaseFieldset(true);
$addressFieldset->setName('address');
$this->add($addressFieldset);

我认为对于我的fieldset的正确寻址可能只是一个问题,但是我无法解释为什么在发布数据之后它会被正确填充。我想要的是他在我的Fieldset中填充setData。

我希望你理解我的问题并且可以帮助我 非常感谢,
斯文

编辑: 我现在分析了一下,这很奇怪,我不知道出了什么问题。 当我调试时,我可以看到$ fieldset-> getValue()返回我需要的所有数据。所以我认为绑定可能是错误的,我这样做是为了逐步调试它:

$values = $this->form->get('address')->getValue();
$addressFieldset = $this->form->get('address');
$aValues = $addressFieldset->getHydrator()->extract($values);
$addressFieldset->bindValues($aValues);

我去了Fieldset.php并且bindValues完成了它应该完成的任务(它只是一个重演(?)),调用水化器并填充我的对象。但是如果我在元素中显示,则所有值都为NULL。 我已经两次检查了我的元素。模型和元素之间唯一不同的是声明的不同顺序。我也在字段集和表单中调用方法setUseAsBaseField(true)。我无法理解为什么数据是值,而不是元素。

2 个答案:

答案 0 :(得分:0)

这很奇怪,因为我有一些东西而且工作很好。你有信心表达式$ _SESSION-> getPersonalData()来返回所需的结果吗?你正在使用一个非常奇怪的会话。 http://framework.zend.com/manual/2.1/en/modules/zend.session.container.html

编辑(对不起我的英文):

  1. 例如,您可以使用不同类型的保湿剂 ArraySerializable(默认情况下,您的实体必须具有getArrayCopy() 和exchangeArray()方法,在你的情况下)默认情况下,ArraySerializable是保湿器。
  2. 首先,您必须使用实体$ form-> bind(new Entity())绑定表单;实体将绑定到基本字段集。如果未指定基本字段集,则实体将与表单绑定,因为表单继承了fieldset。如果实体是聚合,即其属性包含另一个对象,则每个对象都应该是您的fildset。 在构造函数中,您应该使用这个子字段集 $ this-> setObject(new MyChildrenEntity()); 因此,实体属性将被提取到表单中 元件。
  3. 之后,您应该只使用表单,而不是使用表单 元素或字段集。
  4. 您可以传递表单中的任何数据,因此表单元素将获得此信息 值。 $形式 - >使用setData($这 - > Request()方法 - >的getPost());此方法使用内部populateValues()方法。如果表单包含具有适当名称的元素,则会将它们分配给这些值。如果表单具有字段集,则它们也将转移到这些值。
  5. 只要表单无法验证,这些值的实体 不会被分配。这些值仅分配给实体 如果验证成功。 IsValid()方法使用 内部方法bindValues(),如果验证成功。
  6. 成功验证后,您可以使用getData()获取实体 方法$ entity = $ form-> getData();
  7. P.S。:如果你正在做一个复杂的“haсk”,不要被这个简单的解释所冒犯。

答案 1 :(得分:0)

我终于找到了解决方案! 起初,这个链接帮助了我: Populating fieldsets 我没有在表单输入过滤器中集成字段集输入过滤器。
但这不是我必须做的全部。我的Form-Datamodel看起来像这样:

interface IPersonalData
{
    public function getTel();
    public function getBirthday();
    public function getAddress();

    public function setTel($tel);
    public function setAddress(IAddresses $address);
    public function setBirthday($birthday);
}

这只是界面,但地址是一个对象。这就是问题所在。当表单尝试填充字段集时,他只接受数组。所以我必须将getter-method中的对象提取到数组中。 我不认为这是非常有用的,因为我通常希望用这种方法得到我的对象。所以我写了一个方法“getAddressAsArray()”,如下所示:

public function getAddressAsArray()
{
    $oAddressHydrator = new AddressHydrator();
    if(isset($this->address))
    {
        return $oAddressHydrator->extract($this->address);
    }
    return array();
}

我的保湿器的提取方法改变如下:

public function extract($object)
{
    if(!$object instanceof IPersonalData)
    {
        throw new \InvalidArgumentException('$object must be an instance of Application\Model\Product\IPersonalData');
    }
    return array(
        'telephone' => $object->getTel(), 
        'address' => $object->getAddressAsArray(),
        'birthday' => $object->getBirthday(),
    );
}