0
我需要在其父窗體中嵌入一個實體窗體。我跟着官方documentation將表格嵌入到另一個表格中,並有一對多的關係。Symfony 2.8:表單集合和一對多關係沒有正確保存
問題是,雖然我設法正確顯示窗體,當需要保留另一個子實體時,它可以與第2個對象正常工作,當我嘗試創建第三個對象時,它會刪除第二個對象數組並創建第三個。
例:我有了一個一對多的關係,WorkExperience實體
代碼簡歷實體:
實體:
class Curriculum
{
/**
* @ORM\OneToMany(targetEntity="appBundle\Entity\WorkExperience", mappedBy="curriculum", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $workExperience;
public function __construct()
{
$this->workExperience = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add workExperience
*
* @param appBundle\Entity\WorkExperience $workExperience
* @return Curriculum
*/
public function addWorkExperience(appBundle\Entity\WorkExperience $workExperience)
{
$this->workExperience->add($workExperience);
$workExperience->setCurriculum($this);
return $this;
}
/**
* Remove workExperience
*
* @param appBundle\Entity\WorkExperience $workExperience
*/
public function removeWorkExperience(appBundle\Entity\WorkExperience $workExperience)
{
$this->workExperience->removeElement($workExperience);
}
/**
* Get workExperience
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getWorkExperience()
{
return $this->workExperience;
}
}
WorkExperience:
class WorkExperience
{
/**
* @ORM\ManyToOne(targetEntity="appBundle\Entity\Curriculum", inversedBy="workExperience")
* @ORM\JoinColumn(name="curriculum", referencedColumnName="id")
*/
private $curriculum;
/**
* Set curriculum
*
* @param string $curriculum
* @return WorkExperience
*/
public function setCurriculum($curriculum)
{
$this->curriculum = $curriculum;
return $this;
}
/**
* Get curriculum
*
* @return string
*/
public function getCurriculum()
{
return $this->curriculum;
}
}
然後,formType(我只創造了workExperience形式,因爲它是我需要在我collectionType場)
WorkExperienceType:
<?php
namespace appBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use appBundle\Entity\WorkExperience;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Intl\Intl;
use Symfony\Component\Form\Extension\Core\Type\DateType;
class WorkExperienceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('fromDate', DateType::class, array(
'widget' => 'single_text',
'html5' => false,
'attr' => ['class' => 'form-control js-datepicker'],
'format' => 'dd-MM-yyyy',
'label' => 'From')
)
->add('toDate', DateType::class, array(
'widget' => 'single_text',
'html5' => false,
'attr' => ['class' => 'form-control js-datepicker'],
'format' => 'dd-MM-yyyy',
'label' => 'To',
'required' => false,
)
)
->add('ongoing', 'checkbox', array('required' => false,))
->add('jobProfile', EntityType::class, array(
'class' => 'appBundle:JobProfile',
'query_builder' => function (EntityRepository $er) use ($options) {
return $er->createQueryBuilder('j')
->where('j.company = :company')
->setParameter('company', $options['company']);
},
'choice_label' => 'name',
'required' => false,
'placeholder' => 'Job Profile'
))
->add('employerName', 'text', array('label' => "Name"))
->add('employerCity', 'text', array('label' => "City"))
->add('activities', 'textarea', array('label' => "Activities and responsibilities"));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefined('company');
$resolver->setDefaults(array(
'data_class' => WorkExperience::class,
));
}
}
課程控制器:
我只告訴你表單管理因爲它在哪裏我有問題(如果你想知道我不通過一個ID,因爲連接的用戶只能有一個課程)
模板:
{% form_theme formCurriculum _self %}
{% block work_experience_widget %}
<div class="form-group row">
<div class="col-sm-6">
<label for="">Nombre Empresa</label>
{{ form_widget(form.employerName, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="col-sm-5">
<label for="">Categoría Profesional</label>
{{ form_widget(form.jobProfile, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="col-sm-1">
<a href="#" class="btn btn-danger btn-xs text-center remove-tag"><i class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
<div class="form-group row">
<div class="col-sm-3">
<label for="">Fecha desde</label>
<div class="input-group">
{{ form_widget(form.fromDate) }}
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</div>
</div>
<div class="col-sm-5">
<label for="">Fecha hasta</label>
<div class="input-group">
<span class="input-group-addon">
{{ form_widget(form.ongoing) }}
</span>
{{ form_widget(form.toDate) }}
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</div>
</div>
<div class="col-sm-4">
<label for="">Ciudad</label>
{{ form_widget(form.employerCity, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
<div class="form-group">
<label for="">Actividades y Responsabilidades</label>
{{ form_widget(form.activities, {'attr': {'class': 'form-control'}}) }}
{{ form_rest(form) }}
{{ form_errors(form)}}
</div>
<hr />
{% endblock %}
{{ form_start(formCurriculum) }}
<div class="col-lg-8 col-xs-12">
<h3>Experiencia Laboral</h3>
<div class="workExperience" data-prototype="{{ form_widget(formCurriculum.workExperience.vars.prototype)|e('html_attr') }}">
{% for workExperience in formCurriculum.workExperience %}
<div class="workExperienceUnit">
{{ form(workExperience)}}
</div>
{% endfor %}
</div>
<div class="form-group text-right">
{{ form_widget(formCurriculum.save, {'attr': {'class': 'btn btn-blue'}}) }}
</div>
<div class="clearfix"></div>
</div>
{{ form_rest(formCurriculum) }}
{{ form_end(formCurriculum) }}
Ajax和JS的形式收集:
{% block javascripts %}
{{ parent() }}
<script type="text/javascript">
var $collectionHolder;
// setup an "add a tag" link
var $addWorkExperienceLink = $('<button type="button" class="btn btn-primary width100x100 add_workexperience_link"><span class="badge"><i class="glyphicon glyphicon-plus"></i></span> Agregar nueva experiencia laboral</button>');
var $newLinkLi = $('<div class="form-group row"><div class="col-sm-12"></div></div>').append($addWorkExperienceLink);
jQuery(document).ready(function() {
$collectionHolder = $('div.workExperience');
// add the "add a tag" anchor and li to the tags ul
$collectionHolder.append($newLinkLi);
// count the current form inputs we have (e.g. 2), use that as the new
// index when inserting a new item (e.g. 2)
$collectionHolder.data('index', $collectionHolder.find(':input').length);
$addWorkExperienceLink.on('click', function(e) {
// prevent the link from creating a "#" on the URL
e.preventDefault();
// add a new tag form (see next code block)
addWorkExperienceForm($collectionHolder, $newLinkLi);
});
});
function addWorkExperienceForm($collectionHolder, $newLinkLi) {
// Get the data-prototype explained earlier
var prototype = $collectionHolder.data('prototype');
// get the new index
var index = $collectionHolder.data('index');
$collectionHolder.data('index', index + 1);
// Replace '$$name$$' in the prototype's HTML to
// instead be a number based on how many items we have
var newForm = prototype.replace(/__name__/g, index);
// Display the form in the page in an li, before the "Add a tag" link li
var $newFormLi = $('<div class="workExperienceUnit"></div>').append(newForm);
$newLinkLi.before($newFormLi);
$('.remove-tag').click(function(e) {
e.preventDefault();
$(this).parent().parent().parent().remove();
return false;
});
}
// handle the removal, just for this example
$('.remove-tag').click(function(e) {
e.preventDefault();
$(this).parent().parent().parent().remove();
return false;
});
</script>
{% endblock %}
這裏是截圖,事情是,它正確地刪除對象,該onlye問題是創建新對象
時