You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony4.3更新后EntityType首选选项排序失效求助

解决Symfony 4.3+中EntityType首选选项排序问题

针对你遇到的Symfony 4.3升级后preferred_choices丢失排序的问题,我有几个无需在表单构建器外单独创建事件数组的解决方案,推荐优先尝试以下SQL层面的排序方案:

方案一:通过Query Builder的CASE表达式控制全局排序

这个方法利用SQL的条件排序,先把未来事件放在列表最前面(按日期升序),再排列过去的事件(同样按日期升序)。因为preferred_choices会保留这些事件在原列表中的顺序,所以首选选项自然就是升序的:

->add('event', EntityType::class, [
    'class' => 'App:Event',
    'choice_label' => 'name',
    'expanded' => false,
    'multiple' => false,
    'required' => false,
    'placeholder' => '-',
    'query_builder' => function (EntityRepository $er) {
        $now = new \DateTime();
        return $er->createQueryBuilder('e')
            // 添加隐藏字段区分未来/过去事件
            ->addSelect('CASE WHEN e.date > :now THEN 0 ELSE 1 END AS HIDDEN isPast')
            ->setParameter('now', $now)
            // 先按是否为过去事件排序(未来事件在前),再按日期升序
            ->orderBy('isPast', 'ASC')
            ->addOrderBy('e.date', 'ASC');
    },
    'preferred_choices' => function ($event) {
        return $event->getDate() > new \DateTime();
    }
])

这个方案只需要一次数据库查询,完全在Query Builder内处理排序逻辑,保持了代码的简洁性,同时解决了首选选项的排序问题。

方案二:在表单内拆分事件集合(单次查询)

如果不想修改SQL查询,也可以在表单构建器内获取所有事件,然后拆分并分别排序:

->add('event', EntityType::class, [
    'class' => 'App:Event',
    'choice_label' => 'name',
    'expanded' => false,
    'multiple' => false,
    'required' => false,
    'placeholder' => '-',
    'choices' => function (EntityRepository $er) {
        $now = new \DateTime();
        // 获取所有事件并按日期升序排列
        $allEvents = $er->createQueryBuilder('e')
            ->orderBy('e.date', 'ASC')
            ->getQuery()
            ->getResult();
        
        // 拆分未来和过去事件
        $futureEvents = [];
        $pastEvents = [];
        foreach ($allEvents as $event) {
            if ($event->getDate() > $now) {
                $futureEvents[] = $event;
            } else {
                $pastEvents[] = $event;
            }
        }
        
        // 合并后未来事件在前,且各自保持升序
        return array_merge($futureEvents, $pastEvents);
    },
    'preferred_choices' => function ($event) {
        return $event->getDate() > new \DateTime();
    }
])

这个方案只查询一次数据库,然后在内存中拆分集合,确保未来和过去事件都按日期升序排列,preferred_choices会沿用集合中的顺序展示首选选项。

这两个方案都不需要在表单构建器外维护额外的数组,完美贴合你的需求。

内容的提问来源于stack exchange,提问作者Flo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:54:06