问题:使用$ 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()...?
答案 0 :(得分:0)
在您的网页上,检查与您的字段集相关的表单元素名称。它们应该是这样的:yourFieldsetName[yourElementName]
。如果您只看到yourElementName
,则很可能意味着在视图脚本中忘记了prepare()
您的表单。
这正是发生在我身上的事情,在我prepare()
编辑表格之后,所有物体都得到了水分而没有任何问题。
UPDATE =回答评论问题:未解决。这是不好的设计吗?注意:我在视图中使用prepare()。
如果一切正常,你的2个物体应该保湿。 use_as_base_fieldset
标志用于基本上说,'嘿,那是我(字段集)你应该只用对象水合对象/从对象中提取数据'。所以你得到的是一个物体是水合物而另一个物体没有,反之亦然是可以预测的。如果不查看完整的代码,很难说出现了什么问题。我担心发布太多也会花费时间让回答者掌握,而我的经验是这些问题通常没有答案。我通常在像你这样的情况下做的是我在Zend Form
和Fieldset
方法中一步一步地进行水合/提取。我使用\Zend\Debug\Debug::dump($somethingThatYouWantToCheck); die();
。这不是我认为最好的方法,但它有效。
如果我是你,我也会做以下事情。
从您的帖子中,不清楚为什么使用表单的init()
方法。例如,您可以使用init()
方法从表单中填充表单中的某些元素(如<select>
)。当Form
方法中尚未提供某些内容时,init()
运行__construct()
方法,但仅在创建表单实例之后(不是100%确定,仔细检查一下。)
不要担心好/坏的设计。设计是一件非常好的事情,但如果你有一个小型或中型系统,设计考虑因素不会影响系统的性能/复杂性。但是你会花很多时间做正确的事情,而不仅仅是做它,如果它运作正常,就忘了它。
如果您不想使用\Zend\Debug\Debug::dump($somethingThatYouWantToCheck); die();
(我知道这可能非常繁琐),请创建一个字段集并将其附加到您想要的2个字段集。然后在表单中包含此字段集并在此字段集上使用use_as_base_fieldset = true
(当然,您还需要使用附加到当前字段集的2个嵌套对象创建与此字段集对应的对象,并将对象附加到字段集)。
希望这至少有一点帮助。
答案 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()]);