嗨,我得到了我的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()
]);
}
);
}
答案 0 :(得分:1)
Symfony表单有两种主要用法:
Form::submit()
)Form::setData()
和Form::Submit()
) 注意:在两种情况下,Form::handleRequest()
都会在Form::submit()
之前被调用,以检查请求是否可以提交。
我们有2个主要的表单事件类别:
PRE_SET_DATA
PRE_SET_DATA
事件,获取您从其开始的数据的值(在您的情况下为Order
对象),并在将实体对象的数据填充到表单之前立即调度。
您可以使用此事件执行以下操作:
POST_SET_DATA
此事件在调用Form::setData()
方法之后立即触发,可用于:
POST_SET_DATA
和POST_SET_DATA
事件都是在预先填充表单数据时分派的。
PRE_SUBMIT
在调用Form::submit()
或Form::handleRequest()
时触发。此事件可用于:
提交
此事件在PRE_SUBMIT
之后和Form::submit
期间调度(在模型和视图数据归一化之后,以及反归一化之前)。您可以使用此事件执行以下操作:
POST_SUBMIT
此事件在Form::submit()
之后调度。您可以使用此事件执行以下操作:
您应该使用2个事件侦听器,其中一个用于PRE_SET_DATA
,另一个用于POST_SUBMIT
:
OrderType
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)以更新shipping
列表。