【问题标题】:Use CollectionType inside my ThreadType on Symfony display a field for each message, not only the first在 Symfony 上的我的 ThreadType 中使用 CollectionType 为每条消息显示一个字段,而不仅仅是第一个
【发布时间】:2026-02-04 22:30:01
【问题描述】:
<?php

class ThreadType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', TextareaType::class, [
                'attr' => [
                    'class' => 'froala-form-title'
                ]
            ])
            ->add('messages', CollectionType::class, [
                'label' => false,
                'entry_type' => MessageType::class,
                'entry_options' => [
                    'label' => false
                ],
            ]);
    }
    // ...

我的创建新线程的表单没问题,我有线程标题字段和消息字段:

之后,我在我的线程中添加了多条消息,当我想编辑我的线程时,我遇到了这个问题:

我的 CollectionType 字段在我的线程中按消息显示一个文本区域,我只想编辑第一条消息,如何在 Symfony 上执行?

【问题讨论】:

  • 我可能会重组这个,因为您显然不想主要编辑线程,而是第一个帖子和线程标题,以及 显示 其他帖子。 CollectionType 旨在处理相同类型的多个表单,您不能轻易从集合中删除“一个”表单或以不同方式处理它,您的表单需要某种表单事件侦听器并对哪个帖子应该是可编辑的做出反应,但这是一个非常脆弱的设计。
  • 我不想显示其他帖子。在我的最后一个屏幕截图中,我只想显示标题字段和第一个消息字段。但是 CollectionType 不允许我过滤我的线程消息只选择第一个,CollectionType 返回所有消息而不仅仅是第一个,这就是问题所在。
  • 正如我所说,为(第一个)帖子(MessageType)创建一个表单类型,并显示您想要显示的其他内容。通过 ThreadType 处理这个问题并不是特别合乎逻辑,因为您显然不想修改线程,而是修改帖子/消息。这看起来很 javascripty,所以无论如何我可能会加载消息的编辑表单来代替消息。所以...制作一个后期编辑表单而不是线程编辑表单。 ;o)

标签: forms symfony nested-forms


【解决方案1】:

用这段代码解决了:

    $firstThreadMessage = $options['data']->getMessages()[0];

    $builder
        ->add('title', TextareaType::class, [
            'attr' => [
                'class' => 'froala-form-title'
            ]
        ])
        ->add('messages', MessageType::class, [
            'mapped' => false,
            'data' => $firstThreadMessage
        ])
    ;

对于这个formType $options['data'] 是我的线程,我可以通过->getMessages()[0]; 轻松获取线程的第一条消息。此处 mapped 为 false,但由 MessageType 类处理。

【讨论】:

    最近更新 更多