Sonata admin PRE_SUBMIT 表单事件使 admin twig 变量为空

Posted

技术标签:

【中文标题】Sonata admin PRE_SUBMIT 表单事件使 admin twig 变量为空【英文标题】:Sonata admin PRE_SUBMIT form event makes admin twig variable null 【发布时间】:2016-12-19 17:02:55 【问题描述】:

我在管理类中遇到表单事件问题。 我在自定义实体类型中动态添加了选择。通过控制器通过 javascript 将选择添加到数据库中。为了能够验证这些动态选择(在呈现表单后添加),我在字段中添加了一个 PRE_SUBMIT 表单事件管理类。所以在提交表单之前,我从 db 加载新的选择列表,然后将字段删除并添加回表单以更新其选项,如下所示https://gist.github.com/webdevilopers/fef9e296e77bb879d138

在表单类型的 twig 模板中,我使用 sonata_admin.admin 变量来获取所需的数据。 问题是当表单中出现错误时(在表单中的任何其他字段上),twig 模板中的 sonata_admin.admin 变量为空。

感谢帮助

admin::configureFormFields()

$class = 'LibrinfoVarietiesBundle:SelectChoice';
    $repo = $this->getConfigurationPool()->getContainer()->get('doctrine.orm.entity_manager')->getRepository($class);
    $admin = $this;
    $formBuilder = $formMapper->getFormBuilder();

    $formBuilder->addEventListener(FormEvents::SUBMIT, function ($event) use ($formBuilder, $admin, $repo, $class) 
        $form = $event->getForm();
        $subject = $admin->getSubject($event->getData());
        $label = 'librinfo_varieties_admin_variety_regulatory_status_librinfo_core_customchoice';
        $choices = $repo->findBy(array(
            'label' => $label
        ));

        $choiceViews = array();
        foreach ($choices as $choice)
        
            $choiceViews[$choice->getvalue()] = $choice;
        
        if ($form->has('regulatory_status'))
        
            $form->remove('regulatory_status');
        

        $customChoice = $formBuilder->getFormFactory()->createNamed('regulatory_status', 'librinfo_customchoice', null, array(
            'choices' => $choices,
            'class' => $class,
            'auto_initialize' => false,
        ));
        $form->add($customChoice);
    ); 

表单类型ConfigureOptions()

$label = 'librinfo_varieties_admin_variety_regulatory_status_librinfo_core_customchoice';
     $choices = $this->repo->findBy(array(
                'label' => $label
            ));
     $choiceViews = array();
     foreach ($choices as $choice)
     
         $choiceViews[$choice->getvalue()] = $choice;
     

    $resolver->setDefaults(array(
        'choice_label' => 'value',
        'class'        => 'LibrinfoVarietiesBundle:SelectChoice',
        'placeholder'  => '', 
        'choices'      => $choiceViews,
    ));

树枝块

% block librinfo_customchoice_widget %
% set subject = sonata_admin.admin.subject %
% spaceless %
     block('choice_widget') 
    % if subject.fieldset is defined %
        <a id=" subject.fieldset _ subject.field " class="add-choice editable editable-click inline-input" href="#"><i class="fa fa-plus-circle"></i></a>
    % else %
        <a id=" block_prefixes.4 " class="add-choice editable editable-click inline-input" href="#"><i class="fa fa-plus-circle"></i></a>
    % endif %
% endspaceless %
% endblock %

【问题讨论】:

【参考方案1】:

这是因为直接在表单对象槽事件中添加字段时,不会调用奏鸣曲FormTypeFieldExtension

但我找到了一种解决方法,您必须先使用 FormMapper 添加字段。这将设置奏鸣曲管理选项。

然后,在您的事件回调中,取回该字段的当前选项并将它们与您自己的合并:

protected function configureFormFields(FormMapper $formMapper)

    $formMapper
        ->add('date', null, [
            'widget' => 'single_text',
        ])
        ->add('method', EnumType::class, [
            'class' => PaymentMethod::class,
            'translation_domain' => 'global',
            'prefix_label_with_class' => true,
            'attr' => [
                'class' => 'payment-method',
            ],
        ])
        ->add('reference', TextType::class, [
            'required' => false,
            'attr' => [
                'class' => 'payment-reference',
            ]
        ])
        ->add('amount')
    ;

    $builder = $formMapper->getFormBuilder();
    $factory = $builder->getFormFactory();

    $referenceTypeMaker = function (FormEvent $event) use ($factory) 
        $form = $event->getForm();
        $data = $event->getData();

        $paymentMethod = $data instanceof Payment ? $data->getMethod() : $data['method'];

        if (PaymentMethod::CREDIT_NOTE === $paymentMethod) 
            $form->add($factory->createNamed('reference', CreditNoteRefType::class, null, array_merge(
                $form->get('reference')->getConfig()->getOptions(), // Put back original options here.
                [
                    'auto_initialize' => false
                ]
            )));
        
    ;

    $builder->addEventListener(FormEvents::PRE_SET_DATA, $referenceTypeMaker);
    $builder->addEventListener(FormEvents::PRE_SUBMIT, $referenceTypeMaker);

正如您在我的代码示例中看到的那样,reference 字段是 TextType,但也可以是 CreditNoteRefType,具体取决于付款方式的选择。

将已经定义的字段选项放回新的选项可以解决问题。

【讨论】:

感谢您的帮助

以上是关于Sonata admin PRE_SUBMIT 表单事件使 admin twig 变量为空的主要内容,如果未能解决你的问题,请参考以下文章

configureListFields 中的 Sonata Admin 自定义查询

当sonata_type_admin调用时如何在Sonata的Admin类中获取底层对象?

Sonata 管理包:无法删除与 sonata_type_admin 的关系

服务“admin.category”依赖于不存在的服务“sonata.admin.manager.orm”

有没有办法确定 Sonata\AdminBundle\Admin\Admin::configureFormFields() 中的当前操作(创建或编辑)?

Sonata Admin Bundle - 自定义模板