0

我在 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 是主要的,地址是字段集。这似乎工作。然后我把它放在我的表格中:

$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 中填充 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) 方法。我不明白为什么数据在值中而不是在元素中。

4

2 回答 2

0

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

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

  1. 您可以使用不同类型的 hydrator,例如 ArraySerializable (默认情况下,您的实体必须具有 getArrayCopy() 和 exchangeArray() 方法,在您的情况下)ArraySerializable 是默认情况下的 hydrator。
  2. 首先你必须用实体 $form->bind(new Entity()); 绑定一个表单。该实体将绑定到基本字段集。如果未指定基本字段集,实体将与表单绑定,因为表单继承了字段集。如果实体是一个聚合体,即它的属性包含另一个对象,那么这些对象中的每一个都应该是您的 fildset。在构造函数中,这个子字段集你应该使用 $this->setObject(new MyChildrenEntity()); 结果,实体属性将被提取到表单元素中。
  3. 之后,您应该只使用表单,而不是使用它的元素或字段集。
  4. 您可以在表单中传递任何数据,因此表单元素将获取此值。$form->setData($this->getRequest()->getPost()); 此方法使用内部 populateValues() 方法。如果表单具有适当名称的元素,它们将被分配给这些值​​。如果表单有字段集,它们也会被转移到这些值中​​​。
  5. 只要表单验证失败,这些值的实体就不会被赋值。这些值仅在验证成功的情况下才分配给实体。IsValid() 方法如果验证成功则使用内部方法 bindValues()。
  6. 验证成功后,可以使用 getData() 方法获取实体 $entity = $form->getData();

PS:如果你正在做一个复杂的“haсk”,不要被这个简单的解释冒犯。

于 2013-08-09T10:23:13.793 回答
0

我终于找到了解决方案!起初,这个链接帮助了我: 填充字段 集 我没有在表单输入过滤器中集成字段集输入过滤器。
但这不是我要做的全部。我的表单数据模型如下所示:

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

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

这只是接口,但 Address 是一个对象。这就是问题所在。当表单试图填充字段集时,他只接受数组。所以我必须将getter方法中的对象提取到一个数组中。我认为这不是很有用,因为我通常想用这种方法获取我的对象。所以我写了一个方法“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(),
    );
}
于 2013-08-15T10:52:12.820 回答