Существует действительно лучший способ сделать это.
Создание сущности
Создайте два Entity
POPO и назначьте отношение many-to-one
одному из полей дочерней сущности (вы сделали это правильно). Вы также можете определить one-to-many
отношение в родительском
/**
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="Child", mappedBy="parent", cascade={"persist", "remove" }, orphanRemoval=true)
*/
protected $children;
Я не уверен, если это необходимо, но вы должны явно установить отношения в ваших установщиках, просто чтобы быть уверенными. Например, в вашей собственности:
public function addChild(ChildInterface $child)
{
if(!$this->hasChild($child))
{
$this->children->add($child);
$child->setParent($this);
}
}
Doctrine
, вероятно, не использует эти методы для привязки почтовых данных, но наличие этого для себя может решить некоторые сохраняющиеся проблемы.
Создание типа формы
Создание типа формы для обеих сущностей
/**
* This would be the form type for your sub-albums.
*/
class ChildType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
//$builder->add(...);
//...
}
public function getDefaultOptions(array $options) {
return array(
'data_class' => 'Acme\Bundle\DemoBundle\Entity\Child'
);
}
public function getName()
{
return 'ChildType';
}
}
/**
* This would be the form type for your albums.
*/
class ParentType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
// This part here describes the relationship between the two
// form types.
$builder->add('children', 'collection', array(
'type' => new ChildType(),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true
));
}
public function getName()
{
return 'ChildType';
}
}
С опциями allow_add
и allow_delete
вы фактически сообщили Symfony, что пользователь может добавлять или удалять сущности из коллекции. Опция prototype
позволяет вам иметь прототип так называемой подформы на вашей странице.
Контроллер
Вы должны укреплять здесь отношения, чтобы быть в безопасности. Я спрятал это на отдельном уровне менеджера сущностей (у меня есть отдельные менеджеры для более сложных сущностей), но вы наверняка можете сделать это и на своих контроллерах.
foreach($parent->getChildren() as $child)
{
if($child->getParent() === NULL)
{
$child->setParent($parent);
}
}
View
Подготовьте шаблон вашей формы. Прототип должен быть обработан путем вызова form_rest(form)
где-нибудь в вашем шаблоне. Если это не так или вы хотите настроить прототип, вот пример того, как это сделать.
<script id="ParentType_children_prototype" type="text/html">
<li class="custom_prototype_sample">
<div class="content grid_11 alpha">
{{ form_widget(form.children.get('prototype').field1) }}
{{ form_widget(form.children.get('prototype').field2) }}
{{ form_rest(form.children.get('prototype') ) }}
</div>
</li>
</script>
Вы должны будете сделать форму динамической, используя JavaScript. Если вы используете jQuery
, вы можете получить доступ к прототипу, вызвав $('ParentType_children_prototype').html()
. При добавлении нового дочернего элемента в родительский элемент важно заменить все вхождения $$name$$
в прототипе на соответствующий порядковый номер.
Надеюсь, это поможет.
РЕДАКТИРОВАТЬ Я только что заметил, что в справочнике по типу формы Symfony2 есть статья о CollectionType
. У него есть хорошая альтернатива для реализации внешнего интерфейса для этого.