У меня есть Company
, у которого много Employee
с. В моей форме я хочу, чтобы пользователь мог динамически добавлять сотрудников (достаточно просто). EmployeeType
(AbstractType
) - соединение, содержащее имя и фамилию. При отправке формы Symfony, похоже, не переносит данные из формы в конструктор для «нового» сотрудника. Я получаю ArgumentCountError: Too few arguments to function Employee::__construct() ... 0 passed in ... and exactly 3 expected
. Отображение и редактирование работ сотрудников, поэтому я уверен, что мои отношения и т. Д. Все верны.
Сокращенный код:
Компания
class Company
{
protected $employees;
public function __construct()
{
$this->employees = new ArrayCollection();
}
public function addEmployee(Employee $employee)
{
if ($this->employees->contains($employee)) {
return;
}
$this->employees->add($employee);
}
public function removeEmployee(Employee $employee)
{
if (!$this->employees->contains($employee)) {
return;
}
$this->employees->removeElement($employee);
}
}
Employee
class Employee
{
// ... firstName and lastName properties...
public function __construct(Company $company, $firstName, $lastName)
{
$this->company = $company;
$this->company->addEmployee($this);
}
// ...getter and setter for firstName / lastName...
}
CompanyType
class CompanyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('employees', CollectionType::class, [
'entry_type' => EmployeeType::class,
'allow_add' => true,
'allow_delete' => false,
'required' => false,
]);
// ...other fields, some are CollectionType of TextTypes that work correctly...
}
}
EmployeeType
class EmployeeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('firstName')
->add('lastName');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Employee::class,
]);
}
}
CompanyController
class CompanyController
{
// Never mind that this is a show and not edit, etc.
public function showAction()
{
// Assume $this->company is a new or existing Company
$form = $this->createForm(CompanyType::class, $this->company);
$form->handleRequest($this->request);
if ($form->isSubmitted() && $form->isValid()) {
$company = $form->getData();
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($company);
$entityManager->flush();
}
// set flash message, redirect, etc.
}
// ...render view...
}
Выше будет работать при изменении существующих сотрудников, но не при создании новых. Отлаживая из кода Symfony, я вижу, что для новых сотрудников не существует данных, поэтому он пытается найти закрытие или определение для empty_data
в CompanyType
. Я пробовал это в разные стороны (с помощью configureOptions
и empty_data
при создании формы CompanyType::buildForm
), например. https://symfony.com/doc/current/form/use_empty_data.html. Моя интуиция говорит мне, что мне даже не нужно этого делать, потому что данные формы не должны быть пустыми (я явно заполнил поля).
Я тоже пытался использовать модельный трансформатор. В этом случае преобразование из формы (второй аргумент функции, переданный в new CallbackTransformer
) даже не выполняется.
Представление правильно устанавливает атрибуты имени при добавлении новых полей сотрудника, например, form[employees][1][firstName]
и т. Д. Это не проблема. Он также отправляет правильные данные в контроллер. Я подтвердил это, проверив данные отправки формы через CompanyType::onPreSubmit
(используя прослушиватель событий).
У меня также есть CollectionType
из TextType
с для других вещей в CompanyType
, они работают нормально. Таким образом, проблема, похоже, связана с тем, что EmployeeType
является составным (содержит несколько полей).
Надеюсь, вышесказанного достаточно, чтобы проиллюстрировать проблему. Есть идеи?
UPDATE:
Кажется, проблема в том, что * Symanfony не работает с Employee
. Внутри каждое поле передается в Symfony\Component\Form\Form::submit()
. Для существующих сотрудников также передается Employee
. Для нового это null
. Это объясняет, почему он ищет empty_data
, но я не знаю, почему я не могу заставить empty_data
работать.