php - 根据另一个字段中的选择将实体加载到字段中 Symfony PRE_SET_DATA 事件监听器
问题描述
嗨,我收到了 OrderType 表格。
这是我的代码:
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_DATA 根据所选客户端在 ClientsShippings 实体中加载分配给客户端的送货地址。我在 symfony.com 上读了几次,但我无法完全理解这些事件。
有人可以帮我运行它,让我举个例子说明它是如何工作的。也许我以完全不同的方式思考它。
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) {
if(isset($client->getJson()["client"]["firma"]))
{
$firma = $client->getJson()["client"]["imie"];
}
else {
$firma = "";
}
return ''.$firma.' '.$client->getJson()["client"]["imie"] .' '. $client->getJson()["client"]["nazwisko"].'';
},
'label' => 'Wybierz klienta'
))
->add('product', EntityType::class, array(
'data' => $options['product'],
'mapped' => false,
'multiple' => true,
'class' => Products::class,
'attr' => ['class' => 'chosen-select','data-placeholder'=>'Wybierz produkt'],
'choice_label' => function ($product) {
return ''.$product->getJson()["products"]["name"] .' | Stan Magazynowy: '.$product->getJson()["products"]["stock"].'';
},
'label' => 'Wybierz produkty'
))
->add('save', SubmitType::class, [
'label' => 'Zapisz',
'attr' => ['class' => 'btn btn-primary pull-right']])
;
$builder->get('client')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event)
{
$form = $event->getForm();
$form->getParent()->add('shipping', EntityType::class, [
'class' => ClientsShippings::class,
'placeholder' => 'Wybierz adres dostawy',
'choices' => $form->getData()->getclientsShippings()
]);
}
);
}
解决方案
Symfony 表单有两个主要用途:
- 创建一个新实体(
Form::submit()
被称为) - 编辑现有实体(
Form::setData()
并被Form::Submit()
调用)
注意:在这两种情况下,Form::handleRequest()
都会调用之前Form::submit()
检查请求是否可以提交。
我们有 2 类主要的表单事件:
- 预填充表单期间的事件(仅用于编辑实体表单)
- 表单提交期间的事件(用于新建和编辑实体表单)
1. 使用模型数据预填充表单
PRE_SET_DATA
该PRE_SET_DATA
事件获取您开始使用的数据的值(Order
在您的情况下为 object),并在表单被实体对象的数据填充之前被调度。
您可以使用此活动来:
- 在填充期间修改表单数据
- 添加或删除表单域
POST_SET_DATA
此事件在Form::setData()
方法被调用后立即触发,可用于:
- 预填充表单后读取数据
POST_SET_DATA
和事件都POST_SET_DATA
在预填充表单数据期间调度。
2. 表格提交
预提交
Form::submit()
这在或Form::handleRequest()
被调用时被触发。此事件可用于:
- 更改从请求中捕获的数据
- 在提交数据之前添加或删除字段
提交
此事件在之后PRE_SUBMIT
和期间Form::submit
(模型和视图数据规范化之后,非规范化之前)调度。您可以使用此活动来:
- 标准化后更改数据。
POST_SUBMIT
这个事件在Form::submit()
. 您可以使用此活动来:
- 非规范化后获取数据。
回答你的问题
您应该使用 2 个事件侦听器,一个用于PRE_SET_DATA
,一个用于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);
}
);
}
}
您还应该shipping
根据所选客户端进行 AJAX 调用(一些 JavaScript)来更新列表。
推荐阅读
- android - 在平板和手机上运行 AppAndroid 支持多屏
- javascript - 将数据从数据库加载到语义 ui 模式
- angular - 从 Observable 获取布尔值
- java - Android项目的按钮根本不起作用
- reactjs - 根据每个 id 点击编辑 React 功能组件弹出窗口
- ios - Swift 5 - 根据键将变量设置为 plist 值
- sql - 如何使用存储过程从 t-sql 表中现有的两列计算一列的值?
- javascript - 在 IE 浏览器中填充下拉值
- svelte - sveltejs/kit 不接受“npm run start”
- c - 从函数写入时,链表状态保持不变