构建表单时发生错误。
Neither the property "TM" nor one of the methods "getTM()", "isTM()", "hasTM()", "__get()" exist and have public access in class "Nitra\SchemaCDBBundle\Entity\MonthPlan.
错误在于它FormBuilder没有在 MonthPlan 实体类中找到任何方法或 TM 属性。但是我不明白他为什么要在 MonthPlan 实体中寻找这个方法。
我有一个班级MonthPlan,与员工的关系表示班级Employee
/**
* Сотрудник
*
* @ORM\ManyToOne(targetEntity="Employee", inversedBy="monthPlans")
* @Assert\Type(type="Nitra\SchemaCDBBundle\Entity\Employee")
*/
protected $employee;
我需要为班级MonthPlan中的某些员工创建一个表格Employee。为此,我创建了一个类Form并声明了buildForm. 正如您在上次调用中看到的那样$builder->add(),我指定了选择员工所依据的类和查询以及显示结果所依据的属性'property' =>'name',但最后我得到了上面指出的错误。
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('chosenType', 'choice', array(
'required' => true,
'mapped' => false,
'choices' => array(
4 => 'fields.month.eta',
2 => 'fields.month.TM'
),
'label' => 'fields.month.typeEmployee',
'translation_domain' => 'Admin'));
$builder->add('TM', 'entity', array(
'multiple' => false,
'em' => 'default',
'class' => 'NitraSchemaCDBBundle:Employee',
'required' => false,
'label' => 'fields.monthPlan.tm',
'translation_domain' => 'Admin',
'query_builder' => function(EntityRepository $er){
return $er->createQueryBuilder('u')
->andWhere('u.lvl = :lvl')
->setParameter('lvl',2)
->addOrderBy('u.sureName','ASC');
},
'property' =>'name',
));
创建表单的完整代码。有一个父类EditType,里面是根据yml文件生成的。我继承并覆盖它buildForm
namespace Admingenerated\NitraEmployeeBundle\Form\BaseMonthPlanType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Expression;
class EditType extends AbstractType
{
protected $securityContext;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$formOptions = $this->getFormOption('year', array( 'required' => true, 'mapped' => true, 'label' => 'fields.target.choseYear', 'translation_domain' => 'Admin',));
$builder->add('year', new \Nitra\CommonBundle\Form\YearType(), $formOptions);
$formOptions = $this->getFormOption('month', array( 'required' => true, 'mapped' => true, 'label' => 'fields.target.choseMonth', 'translation_domain' => 'Admin',));
$builder->add('month', new \Nitra\CommonBundle\Form\MonthType(), $formOptions);
$formOptions = $this->getFormOption('target', array( 'multiple' => false, 'em' => 'default', 'class' => 'Nitra\\SchemaCDBBundle\\Entity\\Target', 'required' => false, 'label' => 'fields.monthPlan.target', 'translation_domain' => 'Admin',));
$builder->add('target', 'entity', $formOptions);
$formOptions = $this->getFormOption('employee', array( 'multiple' => false, 'em' => 'default', 'class' => 'Nitra\\SchemaCDBBundle\\Entity\\Employee', 'required' => true, 'label' => 'fields.monthPlan.employee', 'translation_domain' => 'Admin',));
$builder->add('employee', 'entity', $formOptions);
$formOptions = $this->getFormOption('summ', array( 'precision' => 12, 'required' => true, 'label' => 'fields.monthPlan.summ', 'translation_domain' => 'Admin',));
$builder->add('summ', 'number', $formOptions);
}
protected function getFormOption($name, array $formOptions)
{
return $formOptions;
}
public function getName()
{
return 'edit_monthplan';
}
public function setSecurityContext($securityContext)
{
$this->securityContext = $securityContext;
}
}
我的自定义表单构建类。
namespace Nitra\EmployeeBundle\Form\Type\MonthPlan;
use Admingenerated\NitraEmployeeBundle\Form\BaseMonthPlanType\EditType as BaseEditType;
use Nitra\SchemaCDBBundle\Repository\EmployeeRepository;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\EntityRepository;
use Nitra\SchemaCDBBundle\Entity\Employee;
use Nitra\CommonBundle\Form\MonthType;
use Nitra\CommonBundle\Form\YearType;
class EditType extends BaseEditType {
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('chosenType', 'choice', array(
'required' => true,
'mapped' => false,
'choices' => array(
4 => 'fields.month.eta',
2 => 'fields.month.TM'
),
'label' => 'fields.month.typeEmployee',
'translation_domain' => 'Admin'));
$builder->add('TM', 'entity', array(
'multiple' => false,
'em' => 'default',
'class' => 'NitraSchemaCDBBundle:Employee',
'required' => false,
'label' => 'fields.monthPlan.tm',
'translation_domain' => 'Admin',
'query_builder' => function(EntityRepository $er){
return $er->createQueryBuilder('u')
->andWhere('u.lvl = :lvl')
->setParameter('lvl',2)
->addOrderBy('u.sureName','ASC');
},
'property' =>'name',
));
}
protected function getFormOption($name, array $formOptions) {
switch ($name) {
case 'employee':
$formOptions['query_builder'] = function (EmployeeRepository $er) {
return $er->getEmployeeAtPositionEta($this->securityContext->getToken()->getUser());
};
break;
}
return $formOptions;
}
}
我怀疑您在创建表单时在控制器中提交了一个实体
在这种情况下,Symfony 将自动使用
$monthPlan表单字段填充实体。Symfony 认为在这种形式中,所有表单字段都与实体字段相关联,在您的情况下,当它在表单中看到一个字段但它不存在于实体中时,它会抱怨。也就是说,在发送表单后的后台,会发生一些事情$monthPlan->setTM($value);,会报错。要避免此行为,请将该字段设置为
'mapped' => false。这有点像表单字段的标志,表示它与提交的实体没有关联,不会处理$monthPlan->setTM($value);您可以创建没有实体的表单,
$this->createForm(MonthPlanType::class, array())并在提交后以您喜欢的任何方式处理数据。如果需要此行为,则将表单中的字段命名为 emplyee 或在实体中创建一个 TM 字段。