简体   繁体   English

Symfony Form EntityType 没有 select 默认情况下呈现的当前值

[英]Symfony Form EntityType doesn't select the current value on render by default

I stumbled upon an odd behavior and I'm still not sure if my solution is the most appropriate one, even though it works now.我偶然发现了一个奇怪的行为,我仍然不确定我的解决方案是否是最合适的,即使它现在有效。

I have 2 entities:我有 2 个实体:

class Recipe
{
    /** [...] */
    public $id;

    /** @ORM\Column(type="string", length=255) */
    public $name;

    /** @ORM\ManyToOne(targetEntity="App\Entity\Location") */
    public $location;
}

class Location
{
    /** [...] */
    public $id;

    /** @ORM\Column(type="string", length=255) */
    public $name;

    /** @ORM\OneToMany(targetEntity="App\Entity\Recipe", mappedBy="location") */
    protected $recipes;
}

Nothing fancy here.这里没什么好看的。 A location can hold several recipes, and a recipe can be in one location at most.一个位置可以存放多个菜谱,一个菜谱最多可以在一个位置。

The recipe form is built as follows:配方表单构建如下:

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add(
                'name',
                TextType::class,
                ['label' => 'Name',]
            )
            ->add(
                'location',
                EntityType::class,
                [
                    'label' => 'Location',
                    'class' => \App\Entity\Location::class,
                    'choice_value' => function ($location) {
                        // Why is this code necessary?
                        return is_object($location)
                            ? $location->getId()    // Object passed (when building choices)
                            : $location;            // int value passed (when checking for selection)
                    },
                    'choice_label' => 'name',
                ]
            )
        ;
    }

Then the controller creates the form and so on.然后 controller 创建表单等等。

    /**
     * @ParamConverter("entity", class="App:Recipe", isOptional="true")
     */
    public function edit(Request $request, object $entity = null) {
        $form = $this->createForm(\App\Form\Recipe::class, $entity ?? new Recipe());
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            // ...
        }
        // ...
    }

My original implementation didn't have the choice_value callback above on the EntityType form element, and the option was never selected when I opened an existing location.我的原始实现在EntityType表单元素上没有上面的choice_value回调,并且当我打开现有位置时从未选择该选项。 But apart from that, everything was working as expected and selecting a value did save it correctly in the database, without more code but Symfony's magic.但除此之外,一切都按预期工作,选择一个值确实将其正确保存在数据库中,没有更多代码,而是 Symfony 的魔力。

Could you tell me why this choice_value is necessary here?你能告诉我为什么这里需要这个choice_value吗? Did I miss something?我错过了什么? Why is the value passed as argument is sometimes an object, and sometimes an integer?为什么作为参数传递的值有时是 object,有时是 integer?

I don't know if it is the cause of the problem, but for EntityType field, you don't need to manually set the choice_value .我不知道这是不是问题的原因,但是对于EntityType字段,您不需要手动设置choice_value

From Symfony docs :来自Symfony 文档

In the EntityType, this is overridden to use the id by default.在 EntityType 中,默认情况下会覆盖它以使用 id。 When the id is used, Doctrine only queries for the objects for the ids that were actually submitted.使用id时,Doctrine只查询实际提交id的对象。

Normally it's not necessary.. Maybe because your relation between entities is uni-directional?通常没有必要.. 也许是因为实体之间的关系是单向的?

Example that works:有效的例子:

In entity Level在实体层面

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\Level", inversedBy="steps")
 */
private $level;

In entity Step在实体步骤

/**
 * @ORM\OneToMany(targetEntity="App\Entity\Step", mappedBy="level")
 */
private $steps;

Then StepType:然后是步骤类型:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('level', EntityType::class, [
            'label' => 'Related level',
            'class' => Level::class,
            'choice_label' => 'position'
        ])
    ;
}

Oh... Found it.哦……找到了。 Actually I had an old DataTransformer that was associated to this field and it was messing with the values.实际上,我有一个与该字段相关联的旧DataTransformer ,它弄乱了这些值。 I didn't need it anymore anyway so just removing it magically fixed the bug.反正我不再需要它了,所以只是将它移除就神奇地修复了这个错误。

Thanks for your help anyway, it did confirm that something wasn't right and forced me to dig deeper.无论如何,感谢您的帮助,它确实证实了某些事情是不对的,并迫使我进行更深入的研究。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM