Forms 在Symfony2中嵌入动态表单
一般信息 我正在使用Symfony 2.8。在这个问题中,两个实体是主体。ObjectElement任务和活动。我将活动作为集合嵌入ObjectElementTask中。到目前为止,一切都很好,一切正常 问题 我在ActivityType中添加了一个evenlistener。因为ObjectElementTaskForm中的ActivityForm的一部分必须是动态的(基于使用表单的经过身份验证的用户…) 当我直接查看ActivityForm时:通过ActivityController(使用以下代码调用表单:Forms 在Symfony2中嵌入动态表单,forms,symfony,Forms,Symfony,一般信息 我正在使用Symfony 2.8。在这个问题中,两个实体是主体。ObjectElement任务和活动。我将活动作为集合嵌入ObjectElementTask中。到目前为止,一切都很好,一切正常 问题 我在ActivityType中添加了一个evenlistener。因为ObjectElementTaskForm中的ActivityForm的一部分必须是动态的(基于使用表单的经过身份验证的用户…) 当我直接查看ActivityForm时:通过ActivityController(使用以下
$editForm=$this->createForm('AppBundle\form\ActivityType',$activity);
)eventlistener正在工作
查看ObjectElementTaksForm时,会出现异常:
类型错误:传递给AppBundle\Form\ActivityType::\uuu construct()的参数1必须实现接口Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface,未给定,在第62行的/home/vpcont1q/public\u html/test/src/AppBundle/Form/ObjectElementTaskType.php中调用
我猜
我猜是因为在ObjectElementTaksForm中,ActivityForm的调用方式与ActivityController不同。然后这个参数(在services.yml中注册)就不能通过。如何确保在嵌入表单时调用注册服务?或我看错方向了吗
代码
以下是我的类型和服务.yml部分:
这是我的活动类型:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
class ActivityType extends AbstractType
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('executionDate')
->add('status'),
->add('scheduledDate')
// grab the user, do a quick sanity check that one exists
$user = $this->tokenStorage->getToken()->getUser();
if (!$user) {
throw new \LogicException(
'You are NOT an authenticated user!'
);
}
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($user) {
//TODO
});
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Activity'
));
}
}
编辑
这似乎有效:
我没有将ActivityType注册为服务,而是将ObjectElementTask注册为服务(也使用Tokenstorage)。
除嵌入ObjectElementTaskType之外,我不使用ActivityType,因此我在services.yml中将ActivityType作为服务删除
app.form.object_element_task:
class: AppBundle\Form\ObjectElementTaskType
arguments: ['@security.token_storage']
tags:
- { name: form.type }
在ObjectElementTaskType中,我添加了构造:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
class ObjectElementTaskType extends AbstractType
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$tokenStorage = $this->tokenStorage;
活动类型我没有改变。这是一种解决方法还是一种方法
app.form.object_element_task:
class: AppBundle\Form\ObjectElementTaskType
arguments: ['@security.token_storage']
tags:
- { name: form.type }
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
class ObjectElementTaskType extends AbstractType
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$tokenStorage = $this->tokenStorage;
->add('activities', 'collection', array(
'entry_type' => new ActivityType($tokenStorage),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))