【发布时间】:2023-03-10 09:20:01
【问题描述】:
我正在尝试在 Symfony2 中实现动态表单。形式很简单,首先用户选择一个经纪商,然后根据那个经纪商选择一个账户。因此,在选择经纪人之前,该帐户将被禁用。
如果是文本输入,read_only => true 可能是一个解决方案,但 select 没有只读属性。所以,我禁用了选择,然后尝试使用 jQuery 启用选择:
$('#form select').prop('disabled', false);
问题是在服务器端,Symfony 无法处理禁用的表单字段。它的值被简单地设置为 null。
我想到了可能的解决方案。首先,我可以在控制器中手动设置字段值,因为我测试了表单字段值实际上是在请求参数中,Symfony 只是忽略它来处理它并将其映射到对象。我认为它会起作用,但这并不是一个很好的解决方案。
其次,我可以通过一些客户端黑客来禁用选择,或者向表单添加隐藏输入并使用 Javascript 手动设置它的值。
这里有标准解决方案吗?
我的表单实体如下所示:
$builder->add('broker', 'entity', array(
'class' => 'MyBundle:Broker',
'property' => 'name',
'query_builder' => function(BrokerRepository $br) {
return $br->getActiveBrokersQuery();
},
'required' => true,
'empty_value' => 'Choose a broker',
));
$builder->add('accountType', 'entity', array(
'class' => 'MyBundle:AccountType',
'empty_value' => 'Choose a broker first',
'disabled' => true,
));
如果我不禁用选择,一切正常,Symfony 完美处理请求。
【问题讨论】:
-
启动一个步进调试器并查看为什么 Symfony 不处理该元素,它的值为 NULL。它是真的 NULL 还是因为浏览器不发送元素而没有设置?由于代码全部开放,您应该从中受益。 Symfony2 Cookbook 中提供了最佳实践。
-
如果我打电话给
$accountAddForm->handleRequest($request);,我会得到$accountAddForm->getData():object(stdClass)#653 (6) { ["__CLASS__"]=> string(42) "CashbackCloud\FcbcBundle\Entity\AccountAdd" ["broker"]=> object(stdClass)#764 (19) { ["__CLASS__"]=> string(38) "CashbackCloud\FcbcBundle\Entity\Broker" ["id"]=> int(8) ... } ["id"]=> NULL ["user"]=> NULL ["accountType"]=> NULL ["accountName"]=> string(4) "3232" } -
但是如果我在提交表单后致电
$request->request->all()。我得到以下信息:array(1) { ["AccountAdd"]=> array(5) { ["broker"]=> string(1) "8" ["accountType"]=> string(2) "54" ["accountName"]=> string(4) "3232" ["save"]=> string(0) "" ["_token"]=> string(40) "b3b118149c1dd7a0f861b0c81d147522d5a3d87f" } }所以值实际上在请求中,但 symfony 只是没有将它映射到对象中。我认为是因为 disabled 值。我说的对吗? -
好的,你更进一步了。现在您必须通过该请求告诉 Symfony 表单元素不再被禁用的条件,因为在您的定义(配置)中它仍然被禁用。 (而且你的昵称都是大写的,读起来不太友好,就这么说吧。)
-
所以我的昵称就是为什么人们从不回答我的问题。 :) 我根据您的建议找到了解决方案。我会在不久的将来提交。 :) 谢谢!