我的设置是一个Symfony 3.4应用,具有典型的'ManyToMany
'-与其他字段的关系,如下所示:
Entity Article
Entity Specialty
Entity ArticleSpecialtyRelation
在一个Form
的一个Article
中,我希望它看起来像是一个ManyToMany
-Relation用EntityType
呈现为multiple=true
的关系,并且expanded=true
,因此Specialty
的所有条目均显示为复选框。
为实现这一点,我创建了一个非orm映射的属性specialties
,它是一个ArrayCollection,在构造函数中初始化,并具有Getter,Adder和Remover。
/**
*
* @var ArrayCollection;
*
*/
protected $specialties;
public function __construct()
{
$this->specialties = new ArrayCollection();
}
/**
* @return Collection|Specialty[]
*/
public function getSpecialties()
{
return $this->specialties;
}
/**
* @param Specialty $specialties
*/
public function addSpecialties(Specialty $specialties)
{
$this->specialties->add($specialties);
}
/**
* @param Specialty $specialties
*/
public function removeSpecialties(Specialty $specialties)
{
$this->specialties->removeElement($specialties);
}
此属性用于将Specialty
实体呈现为复选框:
add('specialties', EntityType::class,array(
'class' => Specialty::class,
'expanded'=>true,
'multiple'=>true,
'label'=>'Specialties',
'required' => false,
'mapped'=>true,
));
要使用来自SpecialtyRelation
的数据填充它,我添加了PreSetData Formevent
:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$article = $event->getData();
if ($article instanceof Article) {
$form->get('specialties')->setData($article->getUsedSpecialties());
}
});
使用过的$artikel
的Getter会迭代$article->getArtikelSpecialties
并返回Specialty
的集合。
在提交之前一切正常。因为formfield是mapped=true
,所以在handleRequest($form)
中某个实体与表单数据混合的地方,当调用$specialty
的加法器时,它将爆炸:
Call to a member function add() on null
因为据我所知,Doctrine从未调用过Constructor
,并且显然初始化了所有ORM-ArrayCollections
而非非映射属性ArrayCollection
的{{1}} -
当然,我可以检查specialties
是否在加法器和卸妆器中初始化并在其中初始化,如果它为null,但是在至少已经有hacky-felt的设置中感觉有点头,我想知道我的设置是否完全愚蠢,尤其是因为我没有发现有人在这里或其他地方尝试这样做(或对此产生问题)。
是否有更好的解决方案?还是我应该只检查Adder和Remover中的ArrayCollection
并从此过上幸福的生活?
另外,只是好奇,还有其他方法可以初始化ArrayCollection
吗?
P.S。如果名称中有错别字,那是因为我将名称翻译成英文。
部分堆栈跟踪
Symfony \ Component \ Debug \ Exception \ FatalThrowableError:调用 成员函数add()为空
at src / Test / Bundle / TestBundle / Entity / Article.php:312 at Test \ Bundle \ TestBundle \ Entity \ Article-> addSpecialties(object(Specialty)) (供应商/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php:674) 在 Symfony \ Component \ PropertyAccess \ PropertyAccessor-> writeCollection(array(object(Article), object(Article)),“ specialties”,object(ArrayCollection), 'addSpecialties','removeSpecialties') (供应商/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php:622) 在 Symfony \ Component \ PropertyAccess \ PropertyAccessor-> writeProperty(array(object(Article), object(Article)),“ specialties”,object(ArrayCollection)) (供应商/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php:216) 在 Symfony \ Component \ PropertyAccess \ PropertyAccessor-> setValue(object(Article), 对象(PropertyPath),对象(ArrayCollection) (供应商/ symfony / symfony / src / Symfony /组件/表格/扩展名/核心/DataMapper/PropertyPathMapper.php:86) 在 Symfony \ Component \ Form \ Extension \ Core \ DataMapper \ PropertyPathMapper-> mapFormsToData(object(RecursiveIteratorIterator), 对象(文章)) (供应商/symfony/symfony/src/Symfony/Component/Form/Form.php:636)在Symfony \ Component \ Form \ Form-> submit(array(),true) (供应商/symfony/symfony/src/Symfony/Component/Form/Form.php:580)