首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >symfony6、select2、ajax和EntityTpe问题

symfony6、select2、ajax和EntityTpe问题
EN

Stack Overflow用户
提问于 2022-09-03 09:53:48
回答 1查看 46关注 0票数 0

我有一个交响乐应用程序,其中一个表单有相当多的“选择”字段,这些字段是用交响乐EntityType定义的,直接从实体中填充。这很好;但是,由于选择字段的数量,通常加载编辑条目的表单非常缓慢,其中有些字段中列出了数千个实体。因此,我决定开始使用select2和Ajax调用,只在用户输入至少2个字符时才填充select字段。这本身就很好,而且速度要快得多;但是,由于数据转换问题,我认为加载和提交表单会遇到很大的问题,因为select2希望定义的数组包含"id“和"text”字段,但是我的字段是使用EntityType定义的。我已经用PRE_SET_DATA和PRE_SUBMIT尝试过各种各样的东西,但是无法让它发挥作用。有人能让select2和Ajax使用交响乐EntityType字段吗?

下面是一些代码片段。

表单字段:

代码语言:javascript
复制
   ->add( 'series', EntityType::class, [
      'required' => false,
      'label' =>  $this->translator->trans( 'form.field.label.series' ),
      'mapped' => true,
      'class' => Series::class,
      'by_reference' => false,
      'expanded' => false,
      'choices' => [],
   ])

select2字段的配置:

代码语言:javascript
复制
   const ajaxSelectSeriesUrl = "{{ path( 'series.select_query_ajax' )|escape( 'js' ) }}";

   const initSelectSeries = ( elem = null ) => {
      $( elem == null ? '.select2-series' : elem ).select2( {
         tags: true,
         theme: "avdb",
         maximumSelectionLength: 1,
         minimumInputLength: 2,
         ajax: {
            url: ajaxSelectSeriesUrl,
            dataType: 'json',
            delay: 250,
            data: function (params) {
               var queryParameters = {
                  q: params.term
               }
               return queryParameters;
            },
            processResults: function ( data ) {
               return {
                  results: data.results,
               };
            },
            cache: true
         },
      } );
   }

如果我选择在我的应用程序中创建一个新项目,那么表单就会在没有问题的情况下加载,并且当我开始输入“系列化”select2字段时,所有这些都可以正常工作,并且我可以选择一个适当的选项。然而,当我提交表单时,事情就出错了,并且我得到了字段包含无效选项的错误。我只能假设这是因为字段使用的是EntityType,因此需要一个实体,而select2则返回一个结果数组。

任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2022-09-05 10:21:05

由于@Laurynas的一篇文章,我设法解决了这个问题。

除了我最初文章中的代码外,我还需要创建PRE_SET_DATA和PRE_SUBMIT事件侦听器(重新创建select字段),确保为select2正确格式化所需的实体数据并插入到“选择”中。

我是这样做的:

代码语言:javascript
复制
class AVItemType extends AbstractType
{
    ...
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        ...
        $builder->addEventListener( FormEvents::PRE_SET_DATA, [ $this, 'onPreSetData' ] );
        $builder->addEventListener( FormEvents::PRE_SUBMIT, [ $this, 'onPreSubmit' ] );
        ...
    }

    private function getSelect2SingleField( FormEvent $event, int $entityId = 0)
    {
        $data = $event->getData();
        $form = $event->getForm();

        $form->add( $fieldName, EntityType::class, [
            'required' => false,
            'label' =>  $this->translator->trans( 'form.field.label.series' ),
            'mapped' => true,
            'class' => Series::class,
            'by_reference' => true,
            'expanded' => false,
            'query_builder' => function( EntityRepository $er ) use ( $entityId ) {
                return $er->createQueryBuilder( 'e' )
                    ->where( 'e.id = :entityId' )
                    ->setParameter( 'entityId', $entityId );
            },
        ] );
    }

    function onPreSetData( FormEvent $event )
    {
        $data = $event->getData();
        $form = $event->getForm();

        if ( ! $data ) :
            return;
        endif;

        // Series
        if ( $data->getSeries() ) :
            $series = $data->getSeries();
            $seriesId = $series ? $series->getid() : 0;
            $this->getSelect2SingleField( event: $event, entityId: $seriesId );
        endif;

        ...
    }

    function onPreSubmit( FormEvent $event )
    {
        $data = $event->getData();
        $form = $event->getForm();

        if ( ! $data ) :
            return;
        endif;

        // Series
        if ( array_key_exists( 'series', $data ) ) :
            $seriesId = $data['series'];
            if ( !( $this->seriesRepository->findOneBy( [ 'id' => $seriesId ] ) ) ) :
                $series = new Series();
                $series->setName( $seriesId );
                $this->seriesRepository->addOrUpdate( $series, true );
                $data['series'] = $series->getId();
                $seriesId = $series->getid();
                $event->setData( $data );
            endif;
            $this->getSelect2SingleField( event: $event, entityId: $seriesId );
        endif;

        ...
    }
    ...
}

现在,当编辑一个现有项时,select2字段被正确地填充到实体数据中,当一个项被保存时,select2字段中的选定条目也被正确保存/分配给该项。

再次感谢Laurynas

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73591263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档