symfony6, select2, ajax and EntityTpe issues



我有一个symphony应用程序,其中一个表单有很多"选择";使用symphony EntityType定义并直接从实体填充的字段。这非常有效;然而,由于选择字段的数量,加载表单以编辑条目通常非常慢,其中一些字段中列出了数千个实体。因此,我决定开始使用select2和Ajax调用,只在用户键入至少2个字符时填充选择字段。这本身效果很好,速度也快得多;然而,由于数据转换问题,我认为加载表单和提交似乎存在巨大问题,因为select2希望定义的数组具有"0";id";以及";文本";字段,但我的字段是使用EntityType定义的。我已经尝试了PRE_SET_DATA和PRE_SUBMIT的各种方法,但就是无法实现。有人能够让select2和Ajax使用symphony EntityType字段吗?

以下是一些代码片段。

表单字段:

->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字段的配置:

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,因此需要一个实体,而select2Ajax返回一个结果数组。

如有任何帮助,我们将不胜感激。

多亏了@Laurynas的一篇帖子,我终于解决了这个问题。

除了我原来文章中的代码外,我还需要创建PRE_SET_DATA和PRE_SUBMIT事件监听器,它们(重新(创建了select字段,确保所需的实体数据正确格式化为select2并插入到";选择";。

我是这样做的:

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!

最新更新