问题描述
我的项目中有一个多对多关系,但是我想修改我的关系表,所以我将其转换为与另一个实体上的联接表的两个多对一关系。
I have a Many to Many relation in my project but I want to modify my relation table, so I converted it into a two Many to One relation with the join table on another entity.
问题是当我尝试呈现两个en初始实体的复选框组时,我将无法使用该复选框。
The problem is that when I try to render a checkbox group of the en two initial entities I'm not able to use then.
这是我的代码:
class Professional extends User
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
...
/**
* @ORM\OneToMany(targetEntity="TurnsProfessional", mappedBy="professional")
*/
private $turns;
...
我的第二个实体
class Turn
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
...
/**
* @ORM\OneToMany(targetEntity="TurnsProfessional", mappedBy="turn")
*/
private $professionals;
...
和加入实体
class TurnsProfessional
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
}
/**
* @ORM\ManyToOne(targetEntity="Turn", inversedBy="professionals")
* @ORM\JoinColumn(name="turn_id", referencedColumnName="id")
*/
private $turn;
/**
* @ORM\ManyToOne(targetEntity="Professional", inversedBy="turns")
* @ORM\JoinColumn(name="professional_id", referencedColumnName="id")
*/
private $professional;
/**
* @ORM\Column(type="boolean")
*/
private $status = 0;
...
我的目标是在专业表单中使用转。我尝试了两件事:
My goal is to create a checkbox list in the Professional form with the turns. I've tried two things:
首先,我尝试在ProfessionalType中将该字段添加为Turn :: class:
First I've tried to add in the ProfessionalType the field as a Turn::class:
...
->add('turns', 'entity',
array('class' => 'AppBundle:TurnsProfessional',
'property' => 'label',
'multiple' => true,
'expanded' => true,
));
...
这里的问题是表单无法呈现复选框。否则,如果我更改类别:
The problem here is that the form does not render the checkboxes. Otherwise if I change the class:
...
->add('turns', 'entity',
array('class' => 'AppBundle:Turn',
'property' => 'label',
'multiple' => true,
'expanded' => true,
));
...
该表单确实呈现所有复选框,但发送时出现错误它:
The form does render all the checkboxes but i get an error on sending it:
我已经按照Oliver所说(已在评论中)编辑了表格:
I´ve edited the form as Oliver said (on comments):
->add($builder->create('turns', CollectionType::class, array(
'entry_type' => TurnsProfessionalType::class,
'by_reference' => false,
)));
使用TurnsProfessionalType
With the TurnsProfessionalType
class TurnsProfessionalType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('status')
->add('turn', EntityType::class,
array('class' => 'AppBundle:Turn',
'property' => 'label',
'multiple' => true,
'expanded' => true,
));
}
public function getBlockPrefix()
{
return 'turns_professional_registration_form';
}
public function getName()
{
return $this->getBlockPrefix();
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => TurnsProfessional::class,
));
}
}
现在我将其渲染为:
{% for turn in form.turns %}
<td><div class="checkbox">{{ form_widget(turn.status)}}<label></label></div></td>
{% endfor %}
但是我需要将每个数据库的标签作为标签
But I need to put as label the database label of each turn
有人可以帮忙吗?
谢谢!
Does anyone can help?Thank you!
推荐答案
专业实体
/**
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="AppBundle\Entity\TurnsProfessional", mappedBy="professional", cascade={"persist"})
*/
private $turns;
public function __construct()
{
$this->turns = new ArrayCollection();
}
/**
* Add turn
*
* @param TurnsProfessional $turns
* @return Professional
*/
public function addTurn(TurnsProfessional $turn)
{
/*
Doctrine only checks the owning side(ManyToOne). So you
need to manually call the join entity setter to keep
your data in sync.
*/
$turn->setProfessional($this);
$this->turns->add($turn);
return $this;
}
/**
* Remove turn
*
* @param TurnsProfessional $turn
* @return Professional
*/
public function removeTurn(TurnsProfessional $turn)
{
/*
Doctrine only checks the owning side(ManyToOne). So you
need to manually call the join entity setter to keep
your data in sync.
*/
$turn->setProfessional();
$this->turns->removeElement($turn);
return $this;
}
/**
* Get turns
*
* @return ArrayCollection
*/
public function getTurns()
{
return $this->turns;
}
旋转实体
/**
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="AppBundle\Entity\TurnsProfessional", mappedBy="turn", cascade={"persist"})
*/
private $professionals;
public function __construct()
{
$this->professionals = new ArrayCollection();
}
/**
* Add professional
*
* @param TurnsProfessional $professional
* @return Turn
*/
public function addProfessional(TurnsProfessional $professional)
{
/*
Doctrine only checks the owning side(ManyToOne). So you
need to manually call the join entity setter to keep
your data in sync.
*/
$professional->setTurn($this);
$this->professionals->add($professional);
return $this;
}
/**
* Remove professional
*
* @param TurnsProfessional $professional
* @return Turn
*/
public function removeProfessional(TurnsProfessional $professional)
{
/*
Doctrine only checks the owning side(ManyToOne). So you
need to manually call the join entity setter to keep
your data in sync.
*/
$professional->setTurn();
$this->professional->removeElement($professional);
return $this;
}
/**
* Get professionals
*
* @return ArrayCollection
*/
public function getProfessionals()
{
return $this->professionals;
}
TurnsProfessional实体
TurnsProfessional Entity
/**
* @var Professional
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Professional", inversedBy="turns", cascade={"persist"})
*/
private $professional;
/**
* @var Turn
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Turn", inversedBy="professionals", cascade={"persist"})
*/
private $turn;
/**
* @var bool
*
* @ORM\Column(name="status", type="boolean")
*/
private $status = true; //You should set a default value to true, since it is non sense to create some value if it not active
/**
* Set professional
*
* @param Professional $professional
* @return TurnsProfessional
*/
public function setProfessional(Professional $professional = null)
{
/*
Using a default null value allows you to unset of the value of
the joined entity when removing in inverse side
(see removeTurn in Professional entity)
*/
$this->professional = $professional;
return $this;
}
/**
* Set turn
*
* @param Turn $turn
* @return TurnsProfessional
*/
public function setTurn(Turn $turn = null)
{
/*
Using a default null value allows you to unset of the value of
the joined entity when removing in inverse side
(see removeProfessional in Turn entity)
*/
$this->turn = $turn;
return $this;
}
ProfessionalType
ProfessionalType
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use AppBundle\Form\TurnsProfessionalType;
class ProfessionalType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('turns', CollectionType::class, array(
'entry_type' => TurnsProfessionalType::class,
'allow_add' => true,
'by_reference' => false, //with by_reference at false you force the call of the setter
))
//other fields
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Professional',
'cascade_validation => true //will also validate joined entities
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'turns_professional_registration_form';
}
}
TurnsProfessionalType
TurnsProfessionalType
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use AppBundle\Entity\Turn;
class TurnsProfessionalType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('turn', EntityType::class, array(
'class' => Turn::class,
'choice_label' => 'label'
));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\TypesProfessional'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'turns_professional_registration_form';
}
}
树枝模板
/*
By default you will have an empty turns collection which
which means you will get no field displayed
that's why you need a addTurn button to fill your collection
and add fields to your form
*/
{{ form_start(form) }}
<ul class="turns" data-prototype="{{ form_widget(form.turns.vars.prototype)|e('html_attr') }}">
{% for turn in form.turns %}
<li>{{ form_row(turn.turn) }}</li>
{% endfor %}
</ul>
{{ form_end(form) }}
<script>
var $collectionHolder;
// setup an "add a turn" link
var $addTurnLink = $('<a href="#" class="add_turn_link">Add a turn</a>');
var $newLinkLi = $('<li></li>').append($addTurnLink);
jQuery(document).ready(function() {
// Get the ul that holds the collection of turns
$collectionHolder = $('ul.turns');
// add the "add a turn" anchor and li to the turns 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);
$addTurnLink.on('click', function(e) {
// prevent the link from creating a "#" on the URL
e.preventDefault();
// add a new turn form (see next code block)
addTurnForm($collectionHolder, $newLinkLi);
});
});
function addTurnForm($collectionHolder, $newLinkLi) {
// Get the data-prototype explained earlier
var prototype = $collectionHolder.data('prototype');
// get the new index
var index = $collectionHolder.data('index');
// 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);
// increase the index with one for the next item
$collectionHolder.data('index', index + 1);
// Display the form in the page in an li, before the "Add a turn" link li
var $newFormLi = $('<li></li>').append(newForm);
$newLinkLi.before($newFormLi);
}
</script>
这篇关于Symfony2复选框列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!