Symfony 4 集合型转换器。如何优雅地显示文本字段中的值?

Symfony 4 collection type transformer. How to elegantly display the values in a text field?

我正在使用 symfony 4。我有一个 ManyToMany 关系(令人惊讶的是与问题无关)具有连接点 table。假设实体 A 可以有多个实体 B,反之亦然。我们还假设 A 拥有 B.

我构建了一个如下所示的表单:

$builder
    ->add('B', TextType::class, [
        'invalid_message' => 'Some invalid message',
        'attr' => [
            'class' => 'tags',
        ]
    ])
    ->add('save', SubmitType::class);

$builder->get('B')
    ->addModelTransformer($this->transformer)
;

接下来我有变压器:

public function transform($bunchOfB_s)
{
    // returns json_encode
}


public function reverseTransform($bunchOfB_s)
{
    // json_decode and transform to B entity
}

关于不单独渲染每个 B,我找不到合适的解决方案。

问题出在 html 本身。目前看起来像这样:

<div class="form-group"><label for="admin_video_tags" class="required">Tags</label><input type="text" id="admin_video_tags" name="admin_video[tags]" required="required" class="tags form-control ui-autocomplete-input" value="[{&quot;name&quot;:&quot;tag_ 6&quot;,&quot;id&quot;:47},{&quot;name&quot;:&quot;tag_ 7&quot;,&quot;id&quot;:48},{&quot;name&quot;:&quot;tag_ 16&quot;,&quot;id&quot;:57}]" autocomplete="off"></div>

我想通过一些 jquery 插件或其他东西使用自动完成功能。我不需要执行 ajax 调用,因为该字段的总值只有大约 15 个。我可以在渲染时简单地将它们传递给视图。

我可以用javascript清除字段。

但是,我觉得这并不是一个优雅的解决方案。这更像是一个黑客。

理想情况下,我正在寻找更优雅的东西。

老实说,我不确定是什么。我希望对 symfony 4 有更好了解的人可以伸出援手。

这不完全是您所要求的,但它是一种更优雅的解决方案,使用复选框或 select 通过一个输入选择多个 B 实体(我不相信你需要一个变压器)。这将只允许输入现有的 B

use App\Entity\B;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
// ...

$builder->add('B', EntityType::class, [
    // looks for choices from this entity
    'class' => B::class,

    // function to get the B's you want as choices
    'query_builder' => function (EntityRepository $er) {
        return $er->createQueryBuilder('b')
            ->orderBy('b.name', 'ASC');
    },

    // uses the B.name property as the visible option string
    'choice_label' => 'name',

    // used to render a select box, check boxes or radios
    // both true for checkboxes
    'multiple' => true,
    'expanded' => true,
    // for select
    'expanded' => false,
]);

另一种方法(但工作量更大),为每个 B 使用单个文本输入是首先使用 TextType::classB 创建一个 formType。然后在 AType 形式中使用 CollectionType::classB 添加到 A。此方法需要一些 javascript 才能将行添加到集合中,但这会在 AType 表单中创建新的 B,而不是使用现有的(没有更多 javascript)。

$builder->add('B', CollectionType::class, [
    // each entry in the array will be a "B" field
    'entry_type' => B::class,

]);

https://symfony.com/doc/current/reference/forms/types/entity.html https://symfony.com/doc/current/reference/forms/types/collection.html