Php 根据另一个字段中的选择将实体加载到字段Symfony PRE_SET_DATA事件侦听器
嗨,我拿到我的订单类型表了 这是我的密码:Php 根据另一个字段中的选择将实体加载到字段Symfony PRE_SET_DATA事件侦听器,php,forms,symfony,entity,Php,Forms,Symfony,Entity,嗨,我拿到我的订单类型表了 这是我的密码: public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('client', EntityType::class, array( 'data' => $options['client'], 'mapped' => false,
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('client', EntityType::class, array(
'data' => $options['client'],
'mapped' => false,
'attr' => ['class' => 'chosen-select','data-placeholder'=>'Wybierz klienta'],
'class' => UserDetails::class,
'choice_label' => function ($client) {
return ''.$firma.' '.$client->getJson()["client"]["imie"] .' '. $client->getJson()["client"]["nazwisko"].'';
},
'label' => 'Wybierz klienta'))
->add('save', SubmitType::class, [
'label' => 'Zapisz',
'attr' => ['class' => 'btn btn-primary pull-right']]) ;
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) {
$form = $event->getForm();
$client =$form->get('client')->getData();
$shipping = null === $client ? array() : $client->getClientsShippings()->getJson()["clients_shippings"]["name"];
$form->add('shipping', EntityType::class, array(
'class' => ClientsShippings::class,
'placeholder' => '',
'choices' => $shipping));
}
);
}
没有错误,但也没有发生任何事情。我不知道如何实现这一点,在选择EventListener客户端之后,根据所选的客户端,PRE_SET_数据将分配给客户端的配送地址加载到ClientsShippings实体中。
我在symfony.com上读过几次这篇文章,但我不能完全理解这些事件
有人能帮我运行一下吗?让我举个例子说明它是如何工作的。也许我的想法完全不同
Symfony表单有两个主要用途:
Form::submit()
被调用)Form::setData()
和Form::Submit()
被调用)Form::submit()
之前调用Form::handleRequest()
,以检查请求是否可以提交
我们有两大类形式事件:
- 预填充表单期间的事件(仅用于编辑实体表单)
- 表单提交期间的事件(用于新建和编辑实体表单)
PRE_SET_DATA
事件,获取您开始使用的数据的值(Order
对象,在您的情况下),并在表单填充实体对象的数据之前进行调度
您可以使用此事件来:
- 在填充期间修改表单数据
- 添加或删除表单字段
Form::setData()
方法后立即激发,可用于:
- 在预填充表单后读取数据
POST\u SET\u DATA
和POST\u SET\u DATA
事件都是在预填充表单数据期间调度的
2.提交表格
预提交
当调用Form::submit()
或Form::handleRequest()
时,将触发此命令。此事件可用于:
- 更改从请求捕获的数据
- 在提交数据之前添加或删除字段
PRE_SUBMIT
之后和Form::SUBMIT
期间(在模型和视图数据规范化之后和反规范化之前)调度。您可以使用此事件来:
- 在标准化后更改数据
表单::submit()之后调度。您可以使用此事件来:
- 取反规范化后的数据
回答你的问题
您应该使用两个事件侦听器,一个用于设置前数据
,另一个用于提交后数据
:
订单类型
class OrderType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('client', EntityType::class, array(
'class' => UserDetails::class
))
->add('save', SubmitType::class)
;
$modifier = function (FormInterface $form, Client $client = null) {
$shippings = null === $client ? array() : $client->getClientsShippings();
$form->add('shipping', EntityType::class, array(
'class' => ClientsShippings::class,
'choices' => $shippings,
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($modifier) {
$orderData = $event->getData();
$modifier($event->getForm(), $orderData->getClient());
}
);
$builder->get('client')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($modifier) {
$client = $event->getForm()->getData();
$modifier($event->getForm()->getParent(), $client);
}
);
}
}
您还应该根据所选的客户端进行AJAX调用(一些JavaScript)以更新配送列表。:)好的,甚至可以根据我们在第一次输入中选择的内容动态更改输入字段的值?好的,我现在了解了它的工作原理,但为什么现在我做的是直接发送到控制器的示例POST_SUBMIT,而不是添加字段?我听不懂你的英语。请重新填写你的问题,看这里;这就是问题所在,也是以前的问题,这就是为什么我有这么多问题,
class OrderType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('client', EntityType::class, array(
'class' => UserDetails::class
))
->add('save', SubmitType::class)
;
$modifier = function (FormInterface $form, Client $client = null) {
$shippings = null === $client ? array() : $client->getClientsShippings();
$form->add('shipping', EntityType::class, array(
'class' => ClientsShippings::class,
'choices' => $shippings,
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($modifier) {
$orderData = $event->getData();
$modifier($event->getForm(), $orderData->getClient());
}
);
$builder->get('client')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($modifier) {
$client = $event->getForm()->getData();
$modifier($event->getForm()->getParent(), $client);
}
);
}
}