gpt4 book ai didi

symfony - empty_data 不适用于复合形式,或者实体没有被实例化(ArgumentCountError : too few arguments to function)

转载 作者:行者123 更新时间:2023-12-03 21:19:44 25 4
gpt4 key购买 nike

我有一个 Company有很多Employee s。在我的表单中,我希望用户能够动态添加员工(足够简单)。 EmployeeType (an AbstractType ) 是复合词,包含名字和姓氏。在提交表单时,Symfony 似乎没有将表单中的数据转移到"new"员工的构造函数中。我有一个错误

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);
}
}
员工
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...
}
公司类型
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...
}
}
员工类型
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,
]);
}
}
公司主管
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 .我已经尝试过这种方法(通过 configureOptionsempty_data 构建 CompanyType::buildForm 表单时的选项),例如 https://symfony.com/doc/current/form/use_empty_data.html .我的直觉告诉我我什至不需要这样做,因为表单数据不应为空(我明确填写了字段)。
我也尝试使用模型转换器。在这种情况下,从表单(传递给 new CallbackTransformer 的第二个函数参数)的转换甚至没有命中。
添加新员工字段时, View 正确设置名称属性,例如 form[employees][1][firstName] ,等等。那不是问题。它还向 Controller 发送正确的数据。我通过 CompanyType::onPreSubmit 检查表单提交数据确认了这一点。 (使用事件监听器)。
我也有 CollectionTypeTextType s 中的其他内容 CompanyType ,这些工作正常。所以这个问题似乎与 EmployeeType 的事实有关。是复合的(包含多个字段)。
希望以上内容足以说明问题。有任何想法吗?
更新:
问题似乎是没有 Employee 的实例化供 Symfony 使用。在内部,每个字段都被传递给 Symfony\Component\Form\Form::submit() .对于现有员工,还有 Employee传入。对于新的,它是 null .这就解释了为什么它要寻找 empty_data ,但我不知道为什么我不能得到 empty_data上类。

最佳答案

解决方案是定义 empty_data复合形式 ,而不是 CollectionType形式。

我的情况有点奇怪,因为我还需要Company的实例在我的 EmployeeType ,因为它必须传递给 Employee 的构造函数.我通过将 Company 作为表单选项传入 configureOptions 来完成此操作。 (由 Controller 提供),然后进入entry_options .我不知道这是否是最佳实践,但它有效:

公司主管

确保我们传入 Company 实例,以便它可以在 EmployeeType 中使用新建时Employee :

$form = $this->createForm(CompanyType::class, $this->company, [
// This is a form option, valid because it's in CompanyType::configureOptions()
'company' => $this->company,
]);

公司类型
class CompanyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('employees', CollectionType::class, [
// ...

// Pass the Company instance to the EmployeeType.
'entry_options' => [ 'company' => $options['company'] ],

// This was also needed, apparently.
'by_reference' => false,
]);
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
// Allows the controller to pass in a Company instance.
'company' => null,
]);
}
}

员工类型

在这里我们确保 empty_data从表单数据正确构建一个员工。
class EmployeeType extends AbstractType
{
private $company;

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('firstName')
->add('lastName');

// A little weird to set a class property here, but we need the Company
// instance in the 'empty_data' definition in configureOptions(),
// at which point we otherwise wouldn't have access to the Company.
$this->company = $options['company'];
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Employee::class,
'empty_data' => function (FormInterface $form) use ($resolver) {
return new Employee(
$this->company,
$form->get('firstName')->getData(),
$form->get('lastName')->getData(),
);
},
]);
}
}

中提琴!我现在可以添加新员工了。

希望这可以帮助其他人!

关于symfony - empty_data 不适用于复合形式,或者实体没有被实例化(ArgumentCountError : too few arguments to function),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52214079/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com