假设我们想为帖子分配类别,我们使用 EntityType 根据我们拥有的类别数量生成它们,所以我们只需将下一个代码块添加到我们的表单中:
控制器:
->add('categories', EntityType::class, array(
'class' => Category::class,
'choice_label' => 'category_description',
'multiple' => true,
'expanded' => true,
'required' => false,
))
然后在提交表单时将它们保存到数据库中,ManyToMany,使用ArrayCollection:
foreach($post_data['categories'] as $form_category)
{
$database_category = $database_manager->getRepository(Category::class)->find($form_category->getId());
$post->addCategory($database_category);
}
实体:
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
use DoctrineCommonCollectionsCollection;
use DoctrineCommonCollectionsArrayCollection;
/**
* @ORMEntity(repositoryClass="AppRepositoryPostRepository")
*/
class Post
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
...
/**
* @ORMManyToMany(targetEntity="Category", cascade={"persist"})
* @ORMJoinTable(name="junction_table",
* joinColumns={@ORMJoinColumn(name="post_id", referencedColumnName="id")},
* inverseJoinColumns={@ORMJoinColumn(name="category_id", referencedColumnName="id")}
* )
*/
private $categories;
public function __construct() {
$this->categories = new ArrayCollection();
}
...
public function getCategories()
{
return $this->categories;
}
public function addCategory(Category $category): self
{
$this->categories->add($category);
return $this;
}
}
图像:
生成的带有说明和索引的复选框
但是,如果我想在进入编辑模式时预先选中这些复选框,以便用户知道上次选择了哪些复选框,您将如何处理?
另外,如果取消选择,您将如何删除一个?
如果您的表单域映射到实体,则应自动设置数据。您甚至不必手动将类别添加到帖子中。
以下是与您想要执行的操作相匹配的工作代码的完整示例:
//src/Entity/Group.php
namespace AppEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity(repositoryClass="AppRepositoryGroupRepository")
* @ORMTable(name="`group`")
*/
class Group
{
/**
* Group constructor.
*/
public function __construct()
{
$this->players = new ArrayCollection();
}
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
*/
private $id;
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @ORMManyToMany(targetEntity="AppEntityPlayer", inversedBy="groups")
*/
private $players;
/**
* @return mixed
*/
public function getPlayers()
{
return $this->players;
}
/**
* @param mixed $players
*
* @return Group
*/
public function setPlayers($players)
{
$this->players = $players;
return $this;
}
/**
* @param Player $player
*
* @return Group
*/
public function addPlayer(Player $player)
{
$this->players->add($player);
return $this;
}
/**
* @param Player $player
*
* @return Group
*/
public function removePlayer(Player $player)
{
$this->players->removeElement($player);
return $this;
}
}
//src/Entity/Player.php
namespace AppEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity(repositoryClass="AppRepositoryPlayerRepository")
*/
class Player
{
/**
* @return string
*/
public function __toString()
{
return $this->name;
}
/**
* Player constructor.
*/
public function __construct()
{
$this->groups = new ArrayCollection();
}
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
*/
private $id;
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @ORMManyToMany(targetEntity="AppEntityGroup", mappedBy="players")
*/
private $groups;
/**
* @return mixed
*/
public function getGroups()
{
return $this->groups;
}
/**
* @param mixed $groups
*
* @return Player
*/
public function setGroups($groups)
{
$this->groups = $groups;
return $this;
}
/**
* @param Group $group
*
* @return Player
*/
public function addGroup(Group $group)
{
$this->groups->add($group);
return $this;
}
/**
* @param Group $group
*
* @return Player
*/
public function removeGroup(Group $group)
{
$this->groups->removeElement($group);
return $this;
}
}
//src/Form/GroupType.php
namespace AppForm;
use AppEntityGroup;
use AppEntityPlayer;
use SymfonyBridgeDoctrineFormTypeEntityType;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
class GroupType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'players',
EntityType::class,
[
'class' => Player::class,
'multiple' => true,
'expanded' => true,
'required' => false,
]
);
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => Group::class,
]
);
}
}
//src/Controller/GroupController.php
namespace AppController;
use AppEntityGroup;
use AppFormGroupType;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAnnotationRoute;
use SymfonyBundleFrameworkBundleControllerController;
class GroupController extends Controller
{
/**
* @Route("/edit-group/{id}", name="group_edit")
* @param Request $request
* @param Group $group
*
* @return Response
*/
public function editGroup(Request $request, Group $group)
{
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(GroupType::class, $group);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($group);
$em->flush();
}
return new Response(
$this->renderView(
'group/edit-group.html.twig',
array(
'form' => $form->createView(),
)
)
);
}
}
//templates/group/edit-group.html.twig
{% extends 'base.html.twig' %}
{% block body %}
<div class="container">
<div class="row">
<h1>Edit group</h1>
</div>
{{ form_start(form) }}
{{ form_row(form.players) }}
<button type="submit" class="btn btn-success">Edit</button>
{{ form_rest(form) }}
{{ form_end(form) }}
</div>
{% endblock %}