У меня проблемы с реализацией коллекции форм, которая состоит только из фиксированных полей, т.е. allow_add & allow_delete имеют значение false.
У меня есть сущность Board, которая состоит из ряда свойств, включая свойство «компоненты», которое представляет собой отношение «многие ко многим» с сущностью «Компонент». Форма для входа на доску будет иметь раздел Компоненты, но это не тот случай, когда пользователь может добавить любой понравившийся компонент. Вместо этого они будут представлены с фиксированным списком типов компонентов и затем смогут выбрать компонент из выпадающего списка. Например:
- Компонент A: [раскрывающийся список - критерии A]
- Компонент B: [выпадающий -
критерии B]
У меня это частично работает. Я могу добавить поля компонента в BoardType и создать раскрывающееся меню с желаемыми критериями. Я могу отправить форму, и соответствующие поля базы данных сохраняются. Все хорошо. Когда я иду редактировать существующую доску… другая история. Случаются две вещи, которые нежелательны:
- Существующие компоненты для этой платы отображаются со всеми их полями для редактирования. Название компонента, производитель, тип компонента и т. Д. Я не хочу, чтобы все это было доступно пользователю. Я надеюсь, что это просто проблема рендеринга.
- Мои поля фиксированных компонентов по-прежнему отображаются, но в раскрывающихся списках сбрасываются значения заполнителей, которые не отражают то, что фактически хранится в базе данных.
Теперь код (сокращенно для краткости):
Board Entity
/**
* Board
*
* @ORM\Table(name="Board", indexes={@ORM\Index(name="type_id", columns={"type_id"})})
* @ORM\Entity
*/
class Board extends Baseentity
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string|null
*
* @ORM\Column(name="customer_board_name", type="string", length=128, nullable=true)
*/
private $customerBoardName;
/**
* @ORM\ManyToMany(targetEntity="Component")
* @ORM\JoinTable(name="BoardComponentJoin",
* joinColumns={@ORM\JoinColumn(name="board_id")},
* inverseJoinColumns={@ORM\JoinColumn(unique=true)})
*/
private $components;
public function __construct()
{
$this->components = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getCustomerBoardName(): ?string
{
return $this->customerBoardName;
}
public function setCustomerBoardName(?string $customerBoardName): self
{
$this->customerBoardName = $customerBoardName;
return $this;
}
public function getComponents()
{
return $this->components;
}
public function addComponent(Component $component)
{
$this->components->add($component);
}
public function removeComponent(Component $component)
{
$this->components->removeElement($component);
}
Компонент Entity
/**
* Component
*
* @ORM\Table(name="Component", indexes={@ORM\Index(name="type_id", columns={"type_id"}), @ORM\Index(name="company_id", columns={"company_id"})})
* @ORM\Entity
*/
class Component extends Baseentity
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=128, nullable=false)
*/
private $name;
/**
* @var string|null
*
* @ORM\Column(name="description", type="text", length=65535, nullable=true)
*/
private $description;
/**
* @var \ComponentDevicetype
*
* @ORM\ManyToOne(targetEntity="ComponentDevicetype")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="type_id", referencedColumnName="id")
* })
*/
private $type;
/**
* @var \Company
*
* @ORM\ManyToOne(targetEntity="Company", cascade={"persist"})
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="company_id", referencedColumnName="id")
* })
*/
private $company;
BoardType
class BoardType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('customerBoardName', TextType::class, [
'label' => 'Name (Customer)'])
;
$builder
->add('components', CollectionType::class, [
'entry_type' => EmbedComponentType::class,
'allow_add' => false,
'allow_delete' => false])
;
$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$form->get('components')
->add('ddr', EntityType::class, [
'class' => Component::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('comp')
->where('comp.type = 1')
->orderBy('comp.name', 'ASC');},
'choice_label' => 'name',
'placeholder' => 'Choose Component...',
'label' => 'DDR',
'required' => false])
->add('flash', EntityType::class, [
'class' => Component::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('comp')
->where('comp.type = 6')
->orderBy('comp.name', 'ASC');},
'choice_label' => 'name',
'placeholder' => 'Choose Component...',
'label' => 'Flash',
'required' => false]);
});
}
EmbedComponentType
class EmbedComponentType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', EntityType::class, [
'class' => Component::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('comp')
->orderBy('comp.name', 'ASC');},
'choice_label' => 'name',
'placeholder' => 'Choose Component...',]);
}
}
Мои вопросы:
- Как редактировать доску, как я могу получить раскрывающиеся списки Компонент, чтобы точно отражать то, что находится в базе данных?
- Как предотвратить отображение полей ComponentType при редактировании доски?
- Правильно ли я подхожу к этой концепции «фиксированной коллекции»?
Любая помощь приветствуется.