zf2 / zf3使用对象水合多个字段集

时间:2016-11-08 05:42:25

标签: php zend-form zend-framework3 zend-form-fieldset

问题:使用$ 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,但我从数据库中检索数据确定。 注意:如果我设置此标志'use_as_base_fieldset'=>是的,然后填充一个对象(ServiceProvider),反之亦然,如果我将位置字段设置为'true'然后填充。 我一直在寻找几个小时,试验和错误没有成功,我希望这只是我的疲劳,错过了一个简单的设置/配置步骤,以使其工作。

摘要:如何在表单中填充2个或更多实体的2个或更多个Fieldset? Bind(),fieldset-> bindValues()?,

尝试:

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

这些链接很接近但仍无法通过单独的实体填充这两个字段集。 ZF2 Form Hydration with multiple objects and fieldsets https://framework.zend.com/manual/2.4/en/modules/zend.form.collections.html hydrating multiple objects from fieldsets ZF2

集合(产品/品牌/类别)示例使用'use_as_base_fieldset'=>表示“单个”集合。 true,用于bind()...?

2 个答案:

答案 0 :(得分:0)

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

这正是发生在我身上的事情,在我prepare()编辑表格之后,所有物体都得到了水分而没有任何问题。

UPDATE =回答评论问题:未解决。这是不好的设计吗?注意:我在视图中使用prepare()。

如果一切正常,你的2个物体应该保湿。 use_as_base_fieldset标志用于基本上说,'嘿,那是我(字段集)你应该只用对象水合对象/从对象中提取数据'。所以你得到的是一个物体是水合物而另一个物体没有,反之亦然是可以预测的。如果不查看完整的代码,很难说出现了什么问题。我担心发布太多也会花费时间让回答者掌握,而我的经验是这些问题通常没有答案。我通常在像你这样的情况下做的是我在Zend FormFieldset方法中一步一步地进行水合/提取。我使用\Zend\Debug\Debug::dump($somethingThatYouWantToCheck); die();。这不是我认为最好的方法,但它有效。

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

  1. 从您的帖子中,不清楚为什么使用表单的init()方法。例如,您可以使用init()方法从表单中填充表单中的某些元素(如<select>)。当Form方法中尚未提供某些内容时,init()运行__construct()方法,但仅在创建表单实例之后(不是100%确定,仔细检查一下。)

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

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

  4. 希望这至少有一点帮助。

答案 1 :(得分:0)


要处理您需要的多个物体:

1.像您一样为每个对象创建一个带有fieldset的表单。
您必须为每个字段集指定一个名称(例如在构造函数中)。

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()]);