我需要使用事件监听器,因为我需要在表单中显示不同的内容,无论是新的还是已经存在的实体。我可以管理它。
我需要一个Data Transformer,将实体显示为文本,这也是我可以做的事情。
=>但是,我无法同时执行2(数据转换器+事件监听器)。我收到错误: “错误:在非对象上调用成员函数add()”。如果我替换$ builder par $ form,我会收到以下错误:尝试调用类“Symfony \ Component \ Form \ Form”的名为“create”的未定义方法。
有效:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event){
$element = $event->getData();
$form = $event->getForm();
if (!$element || null === $element->getId()) { //new entity
$form->add(...);
} else { //exist already
//...
}
这也有效:
$builder->add( $builder->create('element', 'text')->addModelTransformer($transformer));
但我不能让2同时工作。
$transformer = new ElementObjToStringTransformer($this->em);
$builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event){
$element = $event->getData();
$form = $event->getForm();
if (!$element || null === $element->getId()) { //new entity
$builder->add( $builder->create('element', 'text')->addModelTransformer($transformer));
} else { //exist already
//...
}
});
答案 0 :(得分:2)
我编写了一个表单扩展来支持这个用例而不改变字段类型。
1)创建扩展类。
#include <stdio.h>
#include <stdlib.h>
#define bucket_size 10
int find_the_largest(int arr[],int size);
void display(int arr[],int size);
void radix_sort(int arr[],int size);
int main()
{
printf("------------------------------------------------------\n");
printf(" Hey! This is a radix sort algorithm!\n");
printf("------------------------------------------------------\n\n");
int array[] = {10, 2, 303, 4021, 293, 1, 0, 429, 480, 92, 2999, 14};
int size = sizeof(array)/sizeof(int);
int largest_num = find_the_largest(array,size);
printf("The unsorted array:");
display(array,size);
printf("The radix sort algorithm:\n\n");
radix_sort(array,size);
display(array,size);
return 0;
}
int find_the_largest(int arr[],int size){
int i,max_num=0;
for(i=0;i<size;i++){
if(arr[i]>max_num)
max_num = arr[i];
}
return max_num;
}
void display(int arr[],int size){
int i;
for(i=0;i<size;i++){
printf(" %d",arr[i]);
if(i==size-1)
printf("\n\n");
}
}
void radix_sort(int arr[],int size){
int semi_sort[12];
int max_num = find_the_largest(arr,size);
int i,significant_num = 1;
while(max_num/significant_num>0){
int bucket[bucket_size] = {0};
for(i=0;i<size;i++){
bucket[(arr[i]/significant_num)%10]++;
}
for(i=1;i<size;i++){
bucket[i] += bucket[i-1];
}
for(i=size-1;i>=0;i--){
semi_sort[--bucket[(arr[i]/significant_num)%10]] = arr[i];
}
for(i=0;i<size;i++)
arr[i] = semi_sort[i];
significant_num *= 10;
}
}
2)将此扩展名注册为应用程序服务。
namespace AppBundle\Form\Extension\ModelTransformerExtension
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ModelTransformerExtension extends AbstractTypeExtension {
public function getExtendedType() {
return FormType::class;
}
public function buildForm(FormBuilderInterface $builder, array $options) {
parent::buildForm($builder, $options);
if (isset($options['model_transformer'])) {
$builder->addModelTransformer($options['model_transformer']);
}
}
public function configureOptions(OptionsResolver $resolver) {
parent::configureOptions($resolver);
$resolver->setDefaults(array('model_transformer' => null));
}
}
3)在构建表单时,为任何DataTransformer工具定义services:
app.form.extension.model_transformer:
class: AppBundle\Form\Extension\ModelTransformerExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }
选项。
model_transformer
这个想法也可以扩展到支持public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->addEventListener(FormEvents::PRE_SET_DATA, function ($event) {
$builder = $event->getForm();
$builder->add('myField', TextType::class, array(
'model_transformer' => new MyModelTransformer()
));
});
}
方法。
答案 1 :(得分:1)
简短回答:您无法在侦听器中添加变换器,因为表单已被锁定。
答案很长:有一些解决方案。最常见的,至少对我来说,是创建一个自定义表单类型,您可以在其中添加变换器。 然后添加自定义表单,通常在事件监听器中执行的操作:
class ElementCustomType extends AbstractType {
private $em;
public function __construct(EntityManager $entityManager)
{
$this->em = $entityManager;
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->addModelTransformer(new ElementObjToStringTransformer($this->em))
;
}
public function getParent() {
return 'text';
}
public function getName() {
return 'elementCustom';
}
}
将表单定义为服务:
app.form.type.custom_element:
class: AppBundle\Form\Type\ElementCustomType
arguments: [@doctrine.orm.entity_manager]
tags:
- { name: form.type, alias: elementCustom }
像通常那样在听众中使用表单:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event){
$element = $event->getData();
$form = $event->getForm();
$form->add('element', 'elementCustom')
});