将事件监听器添加到 Symfony3 中动态添加的字段
add an Event Listener to a dynamically added field in Symfony3
我正在使用事件侦听器来动态修改表单。我想在第二个字段中添加另一个事件侦听器。我试过这段代码,但没有用:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('Marque', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Marque',
'placeholder' => '-- Choississez une marque --',
//'mapped' => false
))
->add('Modele', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Modele',
'placeholder' => '-- Choississez un modèle --',
//'mapped' => false
))
->add('nom', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Type',
'placeholder' => '-- Choississez une type --',
//'mapped' => false
))
;
$formModifierM = function (FormInterface $form, Marque $marque = null) {
$modeles = null === $marque ? array() : $marque->getAvailableModeles(); // only in a bidirectional relationship
$placeholder = empty($modeles) ? '-- Choississez un modèle --' : '';
$form->add('Modele', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Modele',
'placeholder' => $placeholder,
'choices' => $modeles,
))
->add('Rechercher', SubmitType::class) ;
};
$formModifierModele = function (FormInterface $form, Modele $modele = null) {
$types = null === $modele ? array() : $modele->getAvailableTypes(); // only in a bidirectional relationship
$placeholder = empty($types) ? '-- Choississez un type --' : '';
$form->add('nom', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Type',
'placeholder' => $placeholder,
'choices' => $types,
))
->add('Rechercher', SubmitType::class) ;
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) use ($formModifierM ,$formModifierModele){
$form = $event->getForm();
$formModifierM($form, null);
$formModifierModele($form, null);
}
);
$builder->get('Marque')->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($formModifierM) {
$form = $event->getForm()->getParent();
$marque = $event->getForm()->getData();
// since we've added the listener to the child, we'll have to pass on
// the parent to the callback functions!
$formModifierM($form, $marque);
}
);
$builder->get('Modele')->addEventListener( // this code did'nt work
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($formModifierModele) {
$form = $event->getForm()->getParent();
$modele = $event->getForm()->getData();
$formModifierModele($form, $modele);
}
);
}
我没有找到解决此问题的方法 problem.Any 请有人帮助我。
我发现了同样的问题,但它对我不起作用
How to add an Event Listener to a dynamically added field using Symfony Forms.
我解决了我的问题。这是我的工作代码:
POST_SUBMIT 必须替换为 PRE_SUBMIT
public function buildForm(FormBuilderInterface $builder, array $options)
{
/** @var \Doctrine\ORM\EntityManager $em */
$em = $options['entity_manager'];
$builder
->add('Marque', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Marque',
'placeholder' => '-- Choississez une marque --',
'required' => false,
//'mapped' => false
))
->add('Modele', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Modele',
'placeholder' => '-- Choississez un modèle --',
'required' => false,
//'mapped' => false
))
->add('nom', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Type',
'placeholder' => '-- Choississez une type --',
'required' => false,
//'mapped' => false
))
;
$formModifierM = function (FormInterface $form, Marque $marque = null) {
$modeles = null === $marque ? array() : $marque->getAvailableModeles(); // only in a bidirectional relationship
$placeholder = empty($modeles) ? '-- Choississez un modèle --' : '';
$form->add('Modele', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Modele',
'placeholder' => $placeholder,
'required' => false,
'choices' => $modeles,
))
->add('Rechercher', SubmitType::class) ;
};
$formModifierModele = function (FormInterface $form, Modele $modele = null) {
$types = null === $modele ? array() : $modele->getAvailableTypes(); // only in a bidirectional relationship
$placeholder = empty($types) ? '-- Choississez un type --' : '';
$form->add('nom', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Type',
'placeholder' => $placeholder,
'required' => false,
'choices' => $types,
))
->add('Rechercher', SubmitType::class) ;
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) use ($formModifierM ,$formModifierModele){
$form = $event->getForm();
$formModifierM($form, null);
$formModifierModele($form, null);
}
);
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function(FormEvent $event) use ($formModifierM ,$formModifierModele , $em) {
$form = $event->getForm();
$data = $event->getData();
if (!isset($data['Modele']) || empty($data['Modele']))
{
$marque_id = $data['Marque'];
$marque = $em->getRepository("EK\PlateformeBundle\Entity\Marque")->find($marque_id);
$formModifierM($form, $marque);
}
else
{
$modele_id = $data['Modele'];
$modele = $em->getRepository("EK\PlateformeBundle\Entity\Modele")->find($modele_id);
$formModifierModele($form, $modele);
}
}
);
}
我认为最好使用链式修饰符并使用 NamedFormBuilder 添加它们,如下例所示。
这是因为在 PRE_SUBMIT 事件中您正在访问请求数据,这在某些情况下可能会破坏您的代码。
$volumeModifier = function(FormInterface $form, ?Vendor $vendor, ?int $year, ?int $volume): void {
if (null === $volume) {
return;
}
$form->add("model", EntityType::class, [
"class" => Model::class,
"required" => false,
"query_builder" => function(ModelRepository $er) use ($vendor, $year, $volume) {
// return builded qb;
},
]);
};
$yearModifier = function(FormInterface $form, ?Vendor $vendor, ?int $year) use ($volumeModifier): void {
if (null === $year) {
return;
}
$volumes = [];//build volumes choices
$builder =
$form->getConfig()->getFormFactory()->createNamedBuilder("volume", ChoiceType::class, null, [
"auto_initialize" => false,
"required" => false,
"choices" => $volumes,
]);
$builder->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($vendor, $year, $volumeModifier) {
/** @var int $volume */
$volume = $event->getForm()->getData();
$volumeModifier($event->getForm()->getParent(), $vendor, $year, $volume);
});
$form->add($builder->getForm());
};
$vendorModifier = function(FormInterface $form, ?Vendor $vendor) use ($yearModifier): void {
if (null === $vendor) {
return;
}
$years = [];// build years choices
$builder =
$form->getConfig()->getFormFactory()->createNamedBuilder("year", ChoiceType::class, null, [
"auto_initialize" => false,
"required" => false,
"choices" => $years,
]);
$builder->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($vendor, $yearModifier) {
/** @var int $year */
$year = $event->getForm()->getData();
$yearModifier($event->getForm()->getParent(), $vendor, $year);
});
$form->add($builder->getForm());
};
$builder->get("vendor")->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($vendorModifier) {
/** @var Vendor $vendor */
$vendor = $event->getForm()->getData();
$vendorModifier($event->getForm()->getParent(), $vendor);
});
我正在使用事件侦听器来动态修改表单。我想在第二个字段中添加另一个事件侦听器。我试过这段代码,但没有用:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('Marque', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Marque',
'placeholder' => '-- Choississez une marque --',
//'mapped' => false
))
->add('Modele', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Modele',
'placeholder' => '-- Choississez un modèle --',
//'mapped' => false
))
->add('nom', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Type',
'placeholder' => '-- Choississez une type --',
//'mapped' => false
))
;
$formModifierM = function (FormInterface $form, Marque $marque = null) {
$modeles = null === $marque ? array() : $marque->getAvailableModeles(); // only in a bidirectional relationship
$placeholder = empty($modeles) ? '-- Choississez un modèle --' : '';
$form->add('Modele', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Modele',
'placeholder' => $placeholder,
'choices' => $modeles,
))
->add('Rechercher', SubmitType::class) ;
};
$formModifierModele = function (FormInterface $form, Modele $modele = null) {
$types = null === $modele ? array() : $modele->getAvailableTypes(); // only in a bidirectional relationship
$placeholder = empty($types) ? '-- Choississez un type --' : '';
$form->add('nom', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Type',
'placeholder' => $placeholder,
'choices' => $types,
))
->add('Rechercher', SubmitType::class) ;
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) use ($formModifierM ,$formModifierModele){
$form = $event->getForm();
$formModifierM($form, null);
$formModifierModele($form, null);
}
);
$builder->get('Marque')->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($formModifierM) {
$form = $event->getForm()->getParent();
$marque = $event->getForm()->getData();
// since we've added the listener to the child, we'll have to pass on
// the parent to the callback functions!
$formModifierM($form, $marque);
}
);
$builder->get('Modele')->addEventListener( // this code did'nt work
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($formModifierModele) {
$form = $event->getForm()->getParent();
$modele = $event->getForm()->getData();
$formModifierModele($form, $modele);
}
);
}
我没有找到解决此问题的方法 problem.Any 请有人帮助我。 我发现了同样的问题,但它对我不起作用 How to add an Event Listener to a dynamically added field using Symfony Forms.
我解决了我的问题。这是我的工作代码: POST_SUBMIT 必须替换为 PRE_SUBMIT
public function buildForm(FormBuilderInterface $builder, array $options)
{
/** @var \Doctrine\ORM\EntityManager $em */
$em = $options['entity_manager'];
$builder
->add('Marque', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Marque',
'placeholder' => '-- Choississez une marque --',
'required' => false,
//'mapped' => false
))
->add('Modele', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Modele',
'placeholder' => '-- Choississez un modèle --',
'required' => false,
//'mapped' => false
))
->add('nom', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Type',
'placeholder' => '-- Choississez une type --',
'required' => false,
//'mapped' => false
))
;
$formModifierM = function (FormInterface $form, Marque $marque = null) {
$modeles = null === $marque ? array() : $marque->getAvailableModeles(); // only in a bidirectional relationship
$placeholder = empty($modeles) ? '-- Choississez un modèle --' : '';
$form->add('Modele', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Modele',
'placeholder' => $placeholder,
'required' => false,
'choices' => $modeles,
))
->add('Rechercher', SubmitType::class) ;
};
$formModifierModele = function (FormInterface $form, Modele $modele = null) {
$types = null === $modele ? array() : $modele->getAvailableTypes(); // only in a bidirectional relationship
$placeholder = empty($types) ? '-- Choississez un type --' : '';
$form->add('nom', EntityType::class, array(
'class' => 'EK\PlateformeBundle\Entity\Type',
'placeholder' => $placeholder,
'required' => false,
'choices' => $types,
))
->add('Rechercher', SubmitType::class) ;
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) use ($formModifierM ,$formModifierModele){
$form = $event->getForm();
$formModifierM($form, null);
$formModifierModele($form, null);
}
);
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function(FormEvent $event) use ($formModifierM ,$formModifierModele , $em) {
$form = $event->getForm();
$data = $event->getData();
if (!isset($data['Modele']) || empty($data['Modele']))
{
$marque_id = $data['Marque'];
$marque = $em->getRepository("EK\PlateformeBundle\Entity\Marque")->find($marque_id);
$formModifierM($form, $marque);
}
else
{
$modele_id = $data['Modele'];
$modele = $em->getRepository("EK\PlateformeBundle\Entity\Modele")->find($modele_id);
$formModifierModele($form, $modele);
}
}
);
}
我认为最好使用链式修饰符并使用 NamedFormBuilder 添加它们,如下例所示。 这是因为在 PRE_SUBMIT 事件中您正在访问请求数据,这在某些情况下可能会破坏您的代码。
$volumeModifier = function(FormInterface $form, ?Vendor $vendor, ?int $year, ?int $volume): void {
if (null === $volume) {
return;
}
$form->add("model", EntityType::class, [
"class" => Model::class,
"required" => false,
"query_builder" => function(ModelRepository $er) use ($vendor, $year, $volume) {
// return builded qb;
},
]);
};
$yearModifier = function(FormInterface $form, ?Vendor $vendor, ?int $year) use ($volumeModifier): void {
if (null === $year) {
return;
}
$volumes = [];//build volumes choices
$builder =
$form->getConfig()->getFormFactory()->createNamedBuilder("volume", ChoiceType::class, null, [
"auto_initialize" => false,
"required" => false,
"choices" => $volumes,
]);
$builder->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($vendor, $year, $volumeModifier) {
/** @var int $volume */
$volume = $event->getForm()->getData();
$volumeModifier($event->getForm()->getParent(), $vendor, $year, $volume);
});
$form->add($builder->getForm());
};
$vendorModifier = function(FormInterface $form, ?Vendor $vendor) use ($yearModifier): void {
if (null === $vendor) {
return;
}
$years = [];// build years choices
$builder =
$form->getConfig()->getFormFactory()->createNamedBuilder("year", ChoiceType::class, null, [
"auto_initialize" => false,
"required" => false,
"choices" => $years,
]);
$builder->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($vendor, $yearModifier) {
/** @var int $year */
$year = $event->getForm()->getData();
$yearModifier($event->getForm()->getParent(), $vendor, $year);
});
$form->add($builder->getForm());
};
$builder->get("vendor")->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($vendorModifier) {
/** @var Vendor $vendor */
$vendor = $event->getForm()->getData();
$vendorModifier($event->getForm()->getParent(), $vendor);
});