我无法预先选择表示多对多关系的多选表单元素中的值。
在我的模型$admin
中,我有正确的数据:一个包含正确CampsTypes的ArrayCollection,但是我不能通过多选来预选合适的选项。
管理员模型
/**
* @var ArrayCollection CampsTypes $campstypes
*
* @ORM\ManyToMany(targetEntity="CampsTypes", inversedBy="admins", cascade={"persist"})
* @ORM\JoinTable(name="campstypes_admins",
* joinColumns={@ORM\JoinColumn(name="admins_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="campstypes_id", referencedColumnName="id")}
* )
*/
private $campstypes;
CampsType模型
/**
* @var ArrayCollection Admins $admins
*
* @ORM\ManyToMany(targetEntity="Admins", mappedBy="campstypes", cascade={"persist"})
*/
private $admins;
然后我定义我的表单选择元素如下
[
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'campTypes',
'required' => false,
'options' => [
'object_manager' => $this->getServiceLocator()->get(EntityManager::class),
'target_class' => CampsTypes::class,
'property' => 'title',
'label' => 'Type de camps autorisés',
'instructions' => 'Ne rien sélectionner si edition d\'un super admin',
],
'attributes' => [
'class' => '',
'multiple' => 'multiple',
]
],
最后,这是我收到表格的行动
protected function saveAdmin(Admins &$admin, &$form, &$msg)
{
$em = $this->getEntityManager();
/** @var CampTypesService $serviceCampTypes */
$serviceCampTypes = $this->getServiceLocator()->get(CampTypesService::class);
$form->bind($admin);
if ($this->getRequest()->isPost()) {
$data = $this->getRequest()->getPost();
if (empty($data['password'])) {
$form->remove('password');
}
$form->setData($data);
if ($form->isValid()) {
if (isset($data['campTypes'])) {
$ids = $form->get('campTypes')->getValue();
$campsTypes = new ArrayCollection($serviceCampTypes->getCampTypesByIds(array_values($ids)));
foreach ($campsTypes as &$campsType) {
/** @var CampsTypes $campsType*/
$campsType->addAdmin($admin);
}
$admin->setCampTypes($campsTypes);
}
$em->persist($admin);
$em->flush();
$msg = 'Sauvegarde des données effectuée';
return;
}
}
return;
}
我没有尝试解决问题 知道我做错了吗?
答案 0 :(得分:0)
你有read this吗?我感觉您正在寻找ObjectMultiCheckbox
而不是ObjectSelect
表单元素。
我自己的代码中的示例
单个选择的用法(用例:设置/更改其他实体的默认货币)
$this->add([
'type' => ObjectSelect::class,
'required' => true,
'name' => 'defaultCurrency',
'options' => [
'object_manager' => $this->getEntityManager(),
'target_class' => Currency::class,
'property' => 'id',
// Use these commented lines if you wish to use a Repository function ('name' => 'repositoryFunctionName')
// 'is_method' => true,
// 'find_method' => [
// 'name' => 'getEnabledCurrencies',
// ],
'display_empty_item' => true,
'empty_item_label' => '---',
'label' => _('Default currency'),
'label_attributes' => [
'class' => '',
'title' => _('Default currency'),
],
'label_generator' => function ($targetEntity) {
/** @var Currency $targetEntity */
return $targetEntity->getName(); // Generates option text based on name property of Entity (Currency in this case)
},
],
]);
用于多个选择(用例:向用户添加/删除(多个)角色)
$this->add([
'name' => 'roles',
'required' => false,
'type' => ObjectMultiCheckbox::class,
'options' => [
'object_manager' => $this->getEntityManager(),
'target_class' => Role::class,
'property' => 'id',
'display_empty_item' => true,
'empty_item_label' => '---',
'label' => _('Roles'),
'label_generator' => function ($targetEntity) {
/** @var Role $targetEntity */
return $targetEntity->getName();
},
],
]);
作为旁注:你应该更多地使用工厂。我看到你在整个课程代码中使用ServiceLocator
,你可以通过工厂注入你的需求来避免这种情况。
如果您需要更多信息,我建议您查看一堆我过去的问题。我有很多,开始类似于你正在寻找的东西。我自己管理了很多这些,并尝试深入描述解决方案。
答案 1 :(得分:0)
所以我做到了!
基本上我的主要问题是我没有对表单的字段名称使用正确的Doctrine命名约定。
因此,我不得不将我的数据库逆向工程化为学说实体,以便与我所做的相比较,以了解它不起作用的地方。 并且还要在两端设置模型(管理员中的管理员和管理员中的camptypse)以使整个shabang工作。
以下是工作类:
管理员表格:
[
'type' => ObjectSelect::class,
'name' => 'campstypes',
'required' => false,
'options' => [
'object_manager' => $this->getServiceLocator()->get(EntityManager::class),
'target_class' => CampsTypes::class,
'property' => 'title',
'label' => 'Type de camps autorisés',
'instructions' => 'Ne rien sélectionner si edition d\'un super admin',
],
'attributes' => [
'class' => '',
'multiple' => 'multiple',
]
],
管理控制器:
protected function saveAdmin(Admins &$admin, &$form, &$msg)
{
$em = $this->getEntityManager();
/** @var CampTypesService $serviceCampTypes */
$serviceCampTypes = $this->getServiceLocator()->get(CampTypesService::class);
$form->bind($admin);
if ($this->getRequest()->isPost()) {
$data = $this->getRequest()->getPost();
if (empty($data['password'])) {
$form->remove('password');
}
$form->setData($data);
if ($form->isValid()) {
if (isset($data['campstypes'])) {
$ids = $form->get('campstypes')->getValue();
$campsTypes = new ArrayCollection($serviceCampTypes->getCampTypesByIds(array_values($ids)));
foreach ($campsTypes as &$campsType) {
/** @var CampsTypes $campsType*/
$campsType->addAdmin($admin);
}
$admin->setCampstypes($campsTypes);
}
$em->persist($admin);
$em->flush();
$msg = 'Sauvegarde des données effectuée';
return;
}
}
return;
}
因此,通过正确地重命名我的表单和模型的字段,并在关系的两个结束模型中设置数据,我得到了它。