Forms Symfony-如何从表单事件调用服务容器对象?

Forms Symfony-如何从表单事件调用服务容器对象?,forms,symfony,events,service,Forms,Symfony,Events,Service,如何从窗体事件调用对象 我创建了一个网站管理员可以创建书籍的表单。通过此表单创建书籍时,我想创建一个产品: public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('title', TextType::class, array( 'attr' => array('class'=>'block1')

如何从窗体事件调用对象

我创建了一个网站管理员可以创建书籍的表单。通过此表单创建书籍时,我想创建一个产品:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('title', TextType::class, array(
            'attr' => array('class'=>'block1')
        ))
        ->addEventListener(
            FormEvents::PRE_SET_DATA,
            array($this, 'onPreSetData')
        )
    ;
}

public function onPreSetData(FormEvent $event)
{
    $book = $event->getData();
    $form = $event->getForm();
    $productFactory = $this->container->get('sylius.factory.product');

}
为此,我需要联系“sylius.factory.product”服务,如下所述:

我可以从任何控制器访问它,但不幸的是,我不能从我定义的BookType类访问它

以下是当我尝试从buildForm()或onPreSetData()函数访问Symfony时返回的错误:

注意:未定义的属性:FrontendBundle\Form\BookType::$container


通过选项将服务传递到表单实际上Symfony文档中对此过程进行了很好的解释:

所以我更新了我调用表单的方式:

$editForm = $this->createForm($form, $item, array(  //WITH SYLIUS
    'sylius_factory_product' => $this->get('sylius.factory.product')
));
public function configureOptions(OptionsResolver $resolver)
{
    $resolver
        ->setDefaults(array(
            'data_class' => 'FrontendBundle\Entity\Book'
        ))
        ->setRequired('sylius_factory_product')
    ;
}
相反:

$editForm = $this->createForm($form, $item); //WIHOUT SYLIUS
public function configureOptions(OptionsResolver $resolver)
{
    $resolver
        ->setDefaults(array(
            'data_class' => 'FrontendBundle\Entity\Book'
        ))
    ;
}
此外,我还调整了configureOptions功能,如下所示:

$editForm = $this->createForm($form, $item, array(  //WITH SYLIUS
    'sylius_factory_product' => $this->get('sylius.factory.product')
));
public function configureOptions(OptionsResolver $resolver)
{
    $resolver
        ->setDefaults(array(
            'data_class' => 'FrontendBundle\Entity\Book'
        ))
        ->setRequired('sylius_factory_product')
    ;
}
相反:

$editForm = $this->createForm($form, $item); //WIHOUT SYLIUS
public function configureOptions(OptionsResolver $resolver)
{
    $resolver
        ->setDefaults(array(
            'data_class' => 'FrontendBundle\Entity\Book'
        ))
    ;
}
您现在可以在buildForm函数中访问您的服务,如下所示:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $productFactory = $options['sylius_factory_product'];
    //...
}

BookType
作为服务,并将
@sylius.factory.product
作为参数传递给它。是什么让您选择了这种方法,而不是简单地将表单类型定义为服务,然后不必担心必须将工厂注入选项?我不知道这种方法。如果我将BookType类定义为服务,我是否能够访问所有factory/services对象?你能解释一下吗?我还应该指出,从表单类型内部实际创建产品可能不是最好的设计。如果它对你有用,那么好吧,但产品和形式实际上是两个不同的东西。