【问题标题】:ZF2: Prefill fieldset dataZF2:预填充字段集数据
【发布时间】:2013-08-06 07:12:03
【问题描述】:

我在 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 有一个 hydrator 和一个绑定,这确实有效,因为所有对象都被完美填充。唯一的问题是,当我打开页面时,输入字段是空的,只填写了生日和电话,直接在表单上

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

$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 完美地完成了它应该做的事情(无论如何它只是一个概括(?)),调用 hydrator 并填充我的对象。但如果我在元素中显示,所有值都是 NULL。 我已经检查了我的元素两次。模型和元素之间的唯一区别是声明顺序不同。我也在字段集和表单中调用了 setUseAsBaseField(true) 方法。我不明白为什么数据是在值中而不是在元素中。

【问题讨论】:

    标签: data-binding zend-framework2 fieldset


    【解决方案1】:

    这很奇怪,因为我有一些东西,而且效果很好。您确定表达式 $_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()); 绑定一个表单。该实体将绑定到基本字段集。如果未指定基本字段集,实体将与表单绑定,因为表单继承了字段集。如果实体是一个聚合体,即它的属性包含另一个对象,那么这些对象中的每一个都应该是您的 fildset。 在构造函数中,您应该使用这个子字段集 $this->setObject(new MyChildrenEntity()); 结果,实体属性将被提取到表单中 元素。
    3. 之后,您应该只使用表单,而不是使用它的 元素或字段集。
    4. 你可以在表单中传递任何数据,所以表单元素会得到这个 价值观。 $form->setData($this->getRequest()->getPost());此方法使用内部 populateValues() 方法。如果表单具有适当名称的元素,它们将被分配给这些值​​。如果表单有字段集,它们也会被转移到这些值。
    5. 只要表单验证失败,这些值的实体 不会被分配。这些值仅分配给实体 在验证成功的情况下。 IsValid() 方法使用 内部方法bindValues()如果验证成功。
    6. 验证成功后,可以使用getData()获取实体 方法 $entity = $form->getData();

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

    【讨论】:

    • 是的,我确定,(请参阅我的编辑)。数据已绑定,但不在元素中。好吧,我不使用zend session(内部原因),我通过“容器”减少了会话,以避免与太多变量名混淆。但是 $_SESSION 也确实很好用;)
    • 这六点我都检查过了,还是不行。我将自己的 Hydrator 与“HydratorInterface”一起使用,现在将其更改为默认的 ArraySerializable,但没有任何改变。谢谢你的第二点,它对我理解这个基本方法有很大帮助,但不幸的是没有解决我的问题。我刚刚和一位同事交谈,这可能是问题所在: 名称包含字段集名称。也许他不能填写这个,因为他只是在寻找公司名称?
    • 感谢您提供此链接,但我不知道这有什么帮助。我不需要我的表单中的集合。我什至不会将它用于 hack,因为字段集的格式非常有限(但这是另一回事)如果此页面有特殊点,您能告诉我在哪里看吗?
    • 我没有看过你的代码,我不太愿意为你写。但是,如果您从此示例中删除表单集合和类别,它将是您需要的 - 表单、一般实体(产品 - 在您的情况下是用户)、高级实体(品牌 - 在您的情况下是用户地址)、控制器和查看脚本。一个很大的帮助 - 它只是为你编写代码。
    【解决方案2】:

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

    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(),
        );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多