动态表单 Symfony 上的约束冲突
Constraint Violation on dynamic form Symfony
我在 Symfony3.4 上工作
我有一个动态形式的国家->地区->城市(3 个不同的实体)。
我可以根据用户选择更改字段,没有任何问题。
但是我无法在数据库中持久化,因为 city 字段(而且只有这个字段)违反了约束
我真的不知道为什么,因为我用同样的方式称呼它们(地区和城市)...
欢迎任何帮助。
这是表格:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$em = $options['entityManager'];
$builder
->add('rue', TextType::class, array(
'label' => 'votre rue',
'required' => true,
))
->add('pays', EntityType::class, array(
'class' => 'AppBundle\Entity\Pays',
'placeholder' => '--choisir--',
'choice_label' => 'nom',
'required' => true
))
;
$addRegion = function (FormInterface $form, Pays $pays = null) {
$regions = null === $pays ? array() : $pays->getRegions();
$form->add('region', EntityType::class, array(
'class' => 'AppBundle\Entity\Region',
'placeholder' => '--choisir une région--',
'choices' => $regions,
'choice_label' => 'nom',
'required' => true
));
};
$addVille = function (FormInterface $form, Region $region = null) {
$villes = null === $region ? array() : $region->getVilles();
$form->add('ville', EntityType::class, array(
'class' => 'AppBundle\Entity\Ville',
'placeholder' => '--choisir une ville--',
'choices' => $villes,
'choice_label' => 'nom',
'required' => true
));
$form->add('submit', SubmitType::class
);
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($addRegion, $addVille){
$form = $event->getForm();
$addVille($form, null);
$addRegion($form, null);
}
);
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) use ($addRegion, $addVille, $em) {
$form = $event->getForm();
$data = $event->getData();
if(isset($data['pays'])){
$paysId = $data['pays'];
$repo = $em->getRepository('AppBundle\Entity\Pays');
$pays = $repo->find($paysId);
$addRegion($form, $pays);
$addVille($form, null);
}
else if(isset($data['region'])){
$regionId = $data['region'];
$repo = $em->getRepository('AppBundle\Entity\Region');
$region = $repo->find($regionId);
$addVille($form, $region);
}
}
);
}
这是模板:
{% block body %}
{% form_theme form 'bootstrap_4_layout.html.twig' %}
{% for message in app.flashes('notice') %}
<div style="color:green;">
{{ message }}
</div>
{% endfor %}
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_end(form) }}
{% 端块 %}
{% 阻止 javascript %}
<script>
var $pays = $('#adresse_pays');
var $region = $('#adresse_region');
var $ville = $('#adresse_ville');
$pays.change(function() {
var $form = $(this).closest('form');
var data = {};
data[$pays.attr('name')] = $pays.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(html) {
$ville.empty()
var select = $(html).find('#adresse_ville > option')
$ville.append(select)
$region.empty()
var select = $(html).find('#adresse_region > option')
$region.append(select)
$region.val($("#adresse_region option:first").val());
console.log('regions')
console.log(select)
}
});
});
$region.change(function() {
var $form = $(this).closest('form');
var data = {};
data[$region.attr('name')] = $region.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(html) {
$ville.empty()
var select = $(html).find('#adresse_ville > option')
$ville.append(select)
$ville.val($("#adresse_ville option:first").val());
console.log('villes')
console.log(select)
}
});
});
</script>
{% 端块 %}
这是表单上的警告(在城市字段旁边):
错误此值无效
多亏了调试栏,我走得更远,好像这个字段发送的不是一个对象,而是一个整数。
我发现另一个字段的不同之处在于城市字段:
Normalized Format submitted is null
而在另一个字段中,例如地区:
Normalized Format
Region {#6035 ▼
-id: 3
-nom: "Catalogne"
-villes: PersistentCollection {#6039 …}
-pays: Pays {#5802 ▶}
-adresses: PersistentCollection {#6041 …}
}
有效!
我拆分函数
$builder->addEventListener(
FormEvents::PRE_SUBMIT, ... in half => 我删除了 else if 并在 "region" 更改时创建了另一个类似的函数来监听。
困扰我的是我不明白为什么它以这种方式工作而不是另一种方式...
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) use ($addRegion, $addVille, $em) {
$form = $event->getForm();
$data = $event->getData();
if(isset($data['pays'])){
$paysId = $data['pays'];
$repo = $em->getRepository('AppBundle\Entity\Pays');
$pays = $repo->find($paysId);
$addRegion($form, $pays);
$addVille($form, null);
}
}
);
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function(FormEvent $event) use ($addVille, $em) {
$form = $event->getForm();
$data = $event->getData();
if(isset($data['region'])){
$regionId = $data['region'];
$repo = $em->getRepository('AppBundle\Entity\Region');
$region = $repo->find($regionId);
$addVille($form, $region);
}
}
);
我在 Symfony3.4 上工作 我有一个动态形式的国家->地区->城市(3 个不同的实体)。 我可以根据用户选择更改字段,没有任何问题。
但是我无法在数据库中持久化,因为 city 字段(而且只有这个字段)违反了约束
我真的不知道为什么,因为我用同样的方式称呼它们(地区和城市)...
欢迎任何帮助。
这是表格:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$em = $options['entityManager'];
$builder
->add('rue', TextType::class, array(
'label' => 'votre rue',
'required' => true,
))
->add('pays', EntityType::class, array(
'class' => 'AppBundle\Entity\Pays',
'placeholder' => '--choisir--',
'choice_label' => 'nom',
'required' => true
))
;
$addRegion = function (FormInterface $form, Pays $pays = null) {
$regions = null === $pays ? array() : $pays->getRegions();
$form->add('region', EntityType::class, array(
'class' => 'AppBundle\Entity\Region',
'placeholder' => '--choisir une région--',
'choices' => $regions,
'choice_label' => 'nom',
'required' => true
));
};
$addVille = function (FormInterface $form, Region $region = null) {
$villes = null === $region ? array() : $region->getVilles();
$form->add('ville', EntityType::class, array(
'class' => 'AppBundle\Entity\Ville',
'placeholder' => '--choisir une ville--',
'choices' => $villes,
'choice_label' => 'nom',
'required' => true
));
$form->add('submit', SubmitType::class
);
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($addRegion, $addVille){
$form = $event->getForm();
$addVille($form, null);
$addRegion($form, null);
}
);
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) use ($addRegion, $addVille, $em) {
$form = $event->getForm();
$data = $event->getData();
if(isset($data['pays'])){
$paysId = $data['pays'];
$repo = $em->getRepository('AppBundle\Entity\Pays');
$pays = $repo->find($paysId);
$addRegion($form, $pays);
$addVille($form, null);
}
else if(isset($data['region'])){
$regionId = $data['region'];
$repo = $em->getRepository('AppBundle\Entity\Region');
$region = $repo->find($regionId);
$addVille($form, $region);
}
}
);
}
这是模板:
{% block body %}
{% form_theme form 'bootstrap_4_layout.html.twig' %}
{% for message in app.flashes('notice') %}
<div style="color:green;">
{{ message }}
</div>
{% endfor %}
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_end(form) }}
{% 端块 %}
{% 阻止 javascript %}
<script>
var $pays = $('#adresse_pays');
var $region = $('#adresse_region');
var $ville = $('#adresse_ville');
$pays.change(function() {
var $form = $(this).closest('form');
var data = {};
data[$pays.attr('name')] = $pays.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(html) {
$ville.empty()
var select = $(html).find('#adresse_ville > option')
$ville.append(select)
$region.empty()
var select = $(html).find('#adresse_region > option')
$region.append(select)
$region.val($("#adresse_region option:first").val());
console.log('regions')
console.log(select)
}
});
});
$region.change(function() {
var $form = $(this).closest('form');
var data = {};
data[$region.attr('name')] = $region.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(html) {
$ville.empty()
var select = $(html).find('#adresse_ville > option')
$ville.append(select)
$ville.val($("#adresse_ville option:first").val());
console.log('villes')
console.log(select)
}
});
});
</script>
{% 端块 %}
这是表单上的警告(在城市字段旁边): 错误此值无效
多亏了调试栏,我走得更远,好像这个字段发送的不是一个对象,而是一个整数。
我发现另一个字段的不同之处在于城市字段:
Normalized Format submitted is null
而在另一个字段中,例如地区:
Normalized Format
Region {#6035 ▼
-id: 3
-nom: "Catalogne"
-villes: PersistentCollection {#6039 …}
-pays: Pays {#5802 ▶}
-adresses: PersistentCollection {#6041 …}
}
有效!
我拆分函数
$builder->addEventListener( FormEvents::PRE_SUBMIT, ... in half => 我删除了 else if 并在 "region" 更改时创建了另一个类似的函数来监听。
困扰我的是我不明白为什么它以这种方式工作而不是另一种方式...
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) use ($addRegion, $addVille, $em) {
$form = $event->getForm();
$data = $event->getData();
if(isset($data['pays'])){
$paysId = $data['pays'];
$repo = $em->getRepository('AppBundle\Entity\Pays');
$pays = $repo->find($paysId);
$addRegion($form, $pays);
$addVille($form, null);
}
}
);
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function(FormEvent $event) use ($addVille, $em) {
$form = $event->getForm();
$data = $event->getData();
if(isset($data['region'])){
$regionId = $data['region'];
$repo = $em->getRepository('AppBundle\Entity\Region');
$region = $repo->find($regionId);
$addVille($form, $region);
}
}
);