1

问题:使用 $form->bind($object) 时,表单中的多个字段集未填充/水合。您如何以 2 个不同的实体对象的形式填充 2 个不同的字段集?我有 2 个字段集:FieldsetA、FieldsetB

表单 RegisterFrom 在其 init() 方法中调用这些

class RegisterForm extends Form
{
    public function init(){
        $this->add(array(
                'name' => 'service_provider_fieldset',
                'type' => ServiceProviderFieldset::class,   // this is one model/entity
        ));

        $this->add(array(
                'name' => 'location_fieldset',
                'type' => LocationFieldset::class,   // this is a separate model/entity
        ));
}
}

创建字段集:(注意注释掉水合尝试)

class ServiceProviderFieldset extends Fieldset
{
    public function init(){
        //parent::__construct($name);
        /*
        $this
        ->setHydrator(new ClassMethodsHydrator(false))
        ->setObject(new ServiceProvider())
        ;
        */

        /*
        $this
        ->setHydrator(new ReflectionHydrator(false))
        ->setObject(new ServiceProvider())
        ;
        */

        $this->add(array(
                'type'=>'Hidden',
                'name'=>'id',
                'options'=>array(
                        'label' => 'Service Provider Id'
                ),
                'attributes'=>array(
                        'id'=>'providerId'
                )
        ));
}
}

控制器:

    $provider = $this->findServiceProviderById($providerId); // this is set from DB call and correctly creates a Provider() object with populated values.
    $location = $this->findServiceProviderLocationById($locId);
    $form = $formManager->get(RegisterForm::class);
    $form->bind($provider);
    $form->bin($location);
// $form->get('service_provider_fieldset')->bindValues(...);

看法:

$formElement = $form->get('service_provider_fieldset')->get('email');
etc...

表单在视图中正确呈现,但没有填充数据。

注意:不使用 Doctrine,但我从数据库中检索数据 OK。注意:如果我将此标志设置 为“use_as_base_fieldset”=> true,则填充 1 个对象(服务提供者),反之亦然,如果我将位置字段设置为“true”,则填充。我一直在寻找几个小时,反复试验但没有成功,我希望这只是我的疲劳,错过了一个简单的设置/配置步骤来让它工作。

摘要:如何在一个表单中使用 2 个或更多实体填充 2 个或更多字段集?绑定(),字段集->绑定值()?

试过:

$form->get('service_provider_fieldset')->allowObjectBinding(true);
        $form->get('service_provider_fieldset')->allowedObjectBindingClass(\Provider\Form\ServiceProviderFieldset::class);

这些是一些关闭但仍无法通过单独的实体填充两个字段集的链接。 具有多个对象和字段集的 ZF2 表单水合 https://framework.zend.com/manual/2.4/en/modules/zend.form.collections.html 水合来自字段集 ZF2 的多个对象

集合(产品/品牌/类别)示例意味着使用“use_as_base_fieldset”=> true 的“单个”集合,用于绑定()...?

4

2 回答 2

0


要处理您需要的多个对象:

1. 为每个对象创建一个包含字段集的表单,就像您所做的那样。
您必须为每个字段集指定一个名称(例如在构造函数中)。

2. 在每个字段集中,我们需要指定水合器,
例如:$this->setHydrator(new ClassMethods());

Zend\Hydrator\ClassMethods用于使用 getter 函数或
Zend\Hydrator\ArraySerializable用于使用 getArrayCopy 方法。

并允许对象类:

$this->setAllowedObjectBindingClass(YourClassObject::class);

您可以在 fieldset的init方法中执行此操作。


3.设置水合器为主要形式:

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


4. 现在在控制器方法中你可以创建 Zend\Stdlib\ArrayObject 的对象:

$obj = new ArrayObject();

然后使用键等于字段集名称添加您的对象:

$obj->offsetSet("fieldset_name", $your_object);

然后您可以将 $obj 绑定到您的表单:

$form->bind($obj);


我希望这有帮助。并且不要忘记准备方法:

return new ViewModel(["form" => $form->prepare()]);
于 2018-05-23T06:51:15.673 回答
0

在您的网页上,检查与您的字段集相关的表单元素名称。它们应该是这样的:yourFieldsetName[yourElementName]. 如果您只看到yourElementName,那很可能意味着prepare()您忘记了视图脚本中的表单。

这正是发生在我身上的事情,在我prepare()编辑表格后,所有物体都毫无问题地被水合了。

更新=回答评论的问题:没有这样解决。这是糟糕的设计吗?注意:我在视图中使用 prepare() on。

如果一切正常,你的 2 个物体应该会补水。use_as_base_fieldset标志用于基本上说,'嘿,这就是我(字段集),你应该只用数据水化对象/从对象中提取数据'。所以你得到的一个物体被水合而另一个没有,反之亦然是可以预测的。如果不查看完整的代码,很难说出出了什么问题。恐怕发布太多也需要时间让回答者掌握,而我的经验是,此类问题通常无人回答。在像你这样的情况下,我通常会一步一步地使用 ZendFormFieldsets 用于水合/提取的方法。我用\Zend\Debug\Debug::dump($somethingThatYouWantToCheck); die();. 这不是我认为的最佳方法,但它确实有效。

如果我是你,我也会做以下事情。

  1. 从您的帖子中,尚不清楚您为什么使用表单的init()方法。init()例如,当您希望从 DB 中填充表单中的某些元素(如 )时,可以使用该方法<select>。当某些东西在方法中尚不可用时Form运行方法,但仅在创建表单实例之后(对此不是 100% 确定,请仔细检查)。init()__construct()

  2. 不要担心好的/坏的设计。设计是一件非常好的事情,但是如果你有一个小型或中型系统,设计考虑不会影响系统的性能/复杂性。而是你会花很多时间做正确的事情,而不是仅仅做它,如果它工作正常,就忘记它。

  3. 如果您不想使用\Zend\Debug\Debug::dump($somethingThatYouWantToCheck); die();(我知道这可能很乏味),请创建一个字段集并将其附加到您想要的 2 个字段集。然后在表单中包含此字段集并use_as_base_fieldset = true在此字段集上使用(当然,您还需要创建与此字段集相对应的对象,其中包含 2 个嵌套对象,这些对象附加到当前字段集,并将对象附加到字段集)。

希望这至少有一点帮助。

于 2017-01-08T10:19:51.370 回答