#forms #symfony #doctrine #arraycollection
#формы #symfony #доктрина #arraycollection
Вопрос:
Моя установка представляет собой приложение Symfony 3.4 с типичным ‘ ManyToMany
‘-отношением с дополнительными полями, что-то вроде этого:
Entity Article
Entity Specialty
Entity ArticleSpecialtyRelation
В Form
для Article
ManyToMany
я хотел, чтобы это выглядело так, как если бы это было EntityType
отношение, отображаемое как multiple=true
с expanded=true
и Specialty
, так что все записи в,, отображаются в виде флажков.
Для достижения этой цели я создал свойство, не отображенное в orm specialties
, которое является ArrayCollection, инициализируется в конструкторе и имеет средство получения, суммирования и удаления.
/**
*
* @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
просто выполняет итерацию $article->getArtikelSpecialties
и возвращает коллекцию Specialty
.
Все это работает до отправки. Поскольку formfield находится mapped=true
где handleRequest($form)
-то там, где объект насыщен данными формы, он взрывается при вызове сумматора для $specialty
:
Call to a member function add() on null
Потому что, как я только что узнал, Constructor
никогда не вызывается Doctrine и, очевидно, инициализирует все ORM- ArrayCollections
но не ArrayCollection
для не отображенного свойства specialties
—
Конечно, я могу проверить, инициализировано ли ArrayCollection
в сумматоре и удалении, и инициализировать его там, если оно равно null, но это просто кажется немного халтурным в уже, по крайней мере, хакерской настройке, и мне интересно, не совсем ли глупа моя настройка, тем более что я не нашел никого, кто пытался бы это сделать (или у кого возникли проблемы с этим) здесь или где-либо еще.
Есть ли лучшее решение для этого или я должен просто проверить ArrayCollection
в сумматоре и удалении и жить долго и счастливо с тех пор? Кроме того, просто любопытно, есть ли какой-либо другой способ инициализировать ArrayCollection
?
P.S. Если в именах есть опечатки, это потому, что я перевел имена на английский.
Частичная трассировка стека
SymfonyComponent DebugException FatalThrowableError: вызов функции-члена add() при null
в src /Test /Bundle /TestBundle/Entity/Article.php:312 в Test Bundle TestBundleEntity Article->addSpecialties(объект (специальность)) (поставщик / symfony / symfony/src /Symfony/Component /PropertyAccess/PropertyAccessor.php:674) в SymfonyComponent PropertyAccessorPropertyAccessor->writeCollection(массив (объект (статья), object(Статья)), ‘specialties’, object (ArrayCollection), ‘addSpecialties’, ‘removeSpecialties’) (поставщик / symfony / symfony/src /Symfony/Component /PropertyAccess/PropertyAccessor.php:622) в SymfonyComponent PropertyAccessPropertyAccessor-> Свойства записи(массив (объект (статья), object(Статья)), ‘specialties’, object (ArrayCollection)) (поставщик / symfony /symfony/src /Symfony/Component /PropertyAccess/PropertyAccessor.php:216) в SymfonyComponent PropertyAccessPropertyAccessor->setValue(объект (статья), объект (PropertyPath), объект (ArrayCollection)) (поставщик / symfony / symfony/src /Symfony/Компонент / Форма / Расширение / Ядро / DataMapper /PropertyPathMapper.php: 86) в SymfonyComponentFormExtensionCoreDataMapperPropertyPathMapper->mapFormsToData(object(RecursiveIteratorIterator) , объект (статья)) (поставщик / symfony/symfony/src/Symfony/Component/Form/Form.php:636) в SymfonyComponentFormForm->submit(array(), true) (поставщик / symfony/symfony/src /Symfony/Component/Form/Form.php:580)
Комментарии:
1.
it explodes when the Adder for $specialty is called
имейте в виду, что, сформулировав это таким образом, ваш вопрос также может автоматически взорваться. Скорее добавьте трассировку исключения в свой вопрос.2. Спасибо! Я, конечно, возражаю 🙂 и добавил точную ошибку и частичную трассировку стека с интересным битом.