自定义格式,写为Extension的(Doctrine) Entity Field。元素呈现为Select2 Element with Tagging。这允许从列表中选择多个项目或添加新值。如果添加了新值,则应创建具有值作为属性的新实体,并将其与formType的基础模型相关联。
我可以使用可用的实体成功渲染select2元素。
提交的值是一个字符串,其中包含(唯一的)选定属性,这些属性当前会导致验证错误(无效值)。它没有像原始字段那样提供所选实体的ID,所以我写了一个应该能够处理它的generic DataTransformer。但是,我无法从TypeExtension 的上下文中attach the transformer to the field as intended。我必须在我的表单中添加变换器。我考虑的另一个选项是suppress the validation Listener enitrely,但这不仅会禁用enitre表单的验证,而且无法正确地将所选值映射到enitities。
实现此功能的最佳方法是什么?由于entity FieldType已经提供了大部分功能,我宁愿尽量避免编写一个完全新的fieldType。
一个选项当然是按the cookbook entry建议的方式进行,即每当我使用该字段时附加变换器:
class MyFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
$entityManager = $options['em'];
$transformer = new ObjectListToStringTransformer($this->em,
[
'class' => $options['class'],
'property' => $options['property'],
'delimiter' => ','
]
);
$builder->add(
$builder->create('entityType', 'entity',
array(
'select2' => true, /*Triggers the select2 template to be used*/
'multiple' => true,
'class' => 'Bundle:Entity',
'property' => 'name'
)
)->addModelTransformer($transformer)
);
}
// ....
}
这可行。但这不是冗长而且不是类型安全的。如果我设置select2 => true
,则必须添加Transformer ,否则将无法验证。所以我真的希望在我的扩展中完成这项工作。我实现这一目标的第一种方法就是错误,就像食谱条目中提到“如何不做”的方式一样:
public function buildForm(FormBuilderInterface $builder, array $options)
{
if ($options['select2']) {
$builder->addModelTransformer(new ObjectListToStringTransformer($this->em,
[
'class' => $options['class'],
'property' => $options['property'],
'delimiter' => ','
]
)
);
}
parent::buildForm($builder, $options);
}
这将为整个表单添加一个变换器,而不仅仅是这个字段。 AFAIK如果它是一个子类(垂直继承)但不在扩展(水平继承)内,我不能做create(...)->addModelTransformer($transformer)
。在添加字段后是否有办法添加它?或者有没有办法通过创建选择字段的子类来实现这一目标?
答案 0 :(得分:0)
显然,实体字段本身有一个已注册的ModelTransformer
(或ViewTransformer
),可在ModelTransformer
之前调用。由于这总是失败,我的变压器永远不会到达。为了解决这个问题,我将addModelTransformer
更改为addViewTransformer
。虽然我的变压器的代码还没有工作,但与它的交互确实如此。