感谢choice_attr
@user2268997 的评论,我找到了相关的博客文章Symfony 2.7 中的新功能:选择表单类型重构,其中详细介绍了(截至目前未记录的)choice_attr
选项的使用。
似乎 Symfony在渲染字段时将属性choice_attr
与in 合并。attr
这意味着我们需要class
覆盖choice_attr
.
我尝试在我定义的代码旁边的代码中执行此操作,attr
但没有运气。看来您需要在表单类型定义中执行此操作。choice_attr
这是添加选项后我的表单的摘录:
namespace MyBundle\Form;
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('roles',
'entity',
[
'class' => 'MyBundle:Role',
'choice_label' => 'name',
'multiple' => true,
'choice_attr' => function () { return ["class" => ""]; }
]);
}
结果如我所愿。我可能还会将其重构为我自己的自定义表单类型,因此我不需要在我的包中重复它。
我现在决定创建一个choice
具有上述所需行为的自定义类型,并在整个应用程序中使用该类型。
这是我的选择类型:
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ChoiceNoOptAttrType extends ChoiceType {
public function configureOptions(OptionsResolver $resolver) {
parent::configureOptions($resolver);
$resolver->setDefault("choice_attr", function () { return ["class" => ""]; });
}
}
我不想重构所有现有的表单来使用这种新类型,所以我选择用我的替换 Symfony 提供的选择类型。这可以通过修改choice
表单类型的服务配置来实现。为此,我为我的包创建了一个编译器通行证。
进一步阅读:创建编译器通行证
namespace MyBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class MyCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition("form.type.choice");
$definition->setClass('MyBundle\Form\ChoiceNoOptAttrType');
}
}
现在剩下要做的就是在包中注册编译器传递。
进一步阅读:如何在 Bundles 中使用编译器通道
namespace MyBundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use MyBundle\DependencyInjection\Compiler\MyCompilerPass;
class MyBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new MyCompilerPass());
}
}
就是这样。现在我的所有choice
字段都在使用我的自定义类,它确保设置的 CSS 类attr
不会传播到我的<option>
元素。