Symfony2 - 使用eventListener修改表单字段

8
我可以帮助您。我有一个带下拉列表的表单,需要根据外部输入修改选项。我猜这应该可以通过事件监听器很好地实现。
$builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function(FormEvent $event) use($input){
                $form = $event->getForm();

                // get existin form child
                // modify list of choices

            }

我看到的所有示例都仅使用FormEvents来添加新字段,但我需要修改现有字段,但我不知道如何访问它。

谢谢帮助


jros:你想以什么方式修改它?你想用不同的类型替换它还是只改变其中一个属性,或者其他不同的方式? - Sean
3个回答

26

虽然原问题已经相当古老,但是我想在这里留下它,以防其他人需要修改字段的特定选项而不必再次复制所有选项:

<?php

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
    $form = $event->getForm();

    // Get configuration & options of specific field
    $config = $form->get('field_to_update')->getConfig();
    $options = $config->getOptions();

    $form->add(
        // Replace original field... 
        'field_to_update',
        $config->getType()->getName(),
        // while keeping the original options... 
        array_replace(
            $options, 
            [
                // replacing specific ones
                'required' => false,
            ]
        )
    );
});

来源:https://github.com/symfony/symfony/issues/8513#issuecomment-21868035


11
我遇到了同样的问题,但是在Symfony 3中。请使用get_class($config->getType()->getInnerType())而不是$config->getType->getName()。这是因为Symfony 3要求类型是完全限定的类名。 - TheNextBigThing
1
你们俩刚刚救了我的一天...谢谢! - Delphine
2
请注意,如果字段上有modelTransformer,则此解决方案无法正常工作。 - ctatro85

3
你可以覆盖原始的子元素。
$builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function(FormEvent $event) use($input){
            $form = $event->getForm();

            $form->add($this->factory->createNamed('name_to_override', 'choice', null,
                 array("choices" => array("choice"=>"value"))
                ));

        }

这对我很有用。

注意:这仅适用于PHP 5.4,因为在PHP 5.3中,闭包中的$this不可用。


2
在5.3版本中,在回调函数之前加上“$that = $this;”,使用“use ($that)”,并将“$this->factory”更改为“$that->factory”。 - moteutsch

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接