Symfony2 Form Event PreSetData Subscriber [英] Symfony2 Form Event PreSetData Subscriber

查看:164
本文介绍了Symfony2 Form Event PreSetData Subscriber的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,用户可以为某些实体创建自定义字段,然后在显示表单时为每个实体对象设置此自定义字段的值。



实现是这样的:



1º)我为表单创建了一个界面,我想要实现此接口的表单。



2º)我为所有表单创建了一个表单扩展名:

  app_core_form_builder.form_extension:
class: App \Core\Bundle\FormBuilderBundle\Form\FormExtension
arguments:[@service_container,@ doctrine.orm.entity_manager]
标签:
- {name :form.type_extension,别名:form}

3º)在此扩展中,如果窗体实现了引用的接口在步骤1中,我添加一个EventSubscriber:

  if($ formType instanceof \App\Core\Bundle\FormBuilderBundle \Model\IAllowCustomField sdInterface){
$ builder-> addEventSubscriber(new FormSubscriber($ this-> container,$ this-> em));
}

4º)此Form订阅者订阅preSetData FormEvent。在这种方法中,我获得与表单关联的实体,并且我获得为其创建的所有自定义字段。
然后我在Symfony2表单类型的帮助下将此字段添加到表单中。
一切顺利,当我显示我的表单时,自定义字段呈现正确。只是为了记录,当我保存表单时,插入自定义字段的值也很好。

  public function preSetData FormEvent $ event){

$ data = $ event-> getData();
$ form = $ event-> getForm();


//在表单创建过程中,通过FormBuilder构造函数调用null作为参数
//调用setData()。你只关心当
// setData被调用时,其中有一个实际的Entity对象(不管是新的
//还是用Doctrine提取)。这个if语句允许你在null条件下跳过
//。
if(null === $ data){
return;
}

$ formEntity = $ form-> getConfig() - > getType() - > getInnerType() - > getEntity();

$ DbEntity = $ this-> em-> getRepository('AppCoreSchemaBundle:DbEntity') - > findOneBy(array('id'=> $ formEntity));

if($ DbEntity&& $ DbEntity-> getAllowCustomFields()){

$ organization = $ this-> container-> get('app_user .user_manager') - > getCurrentOrganization();

if(!$ organization){
throw $ this-> createNotFoundException('Unable to find Organization entity。
}

$ params = array(
'organization'=> $ organization,
'entity'=> $ DbEntity,
);

$ entities = $ this-> em-> getRepository('AppCoreSchemaBundle:DbCustomField') - > getAll($ params);


#运行所有自定义字段并添加适当的字段类型和有效性
foreach($ entities as $ customField){
#配置customfield

FieldConfiguration :: configurate($ customField,$ form);
#问题在这里
#如果对象不为空,那么设置适当的字段数据
if($ data-> getId()){

$ filters = array(
'custom_field'=> $ customField,
'object'=> $ data-> getId(),
);

$ DbCustomFieldValue = $ this-> em-> getRepository('UebCoreSchemaBundle:DbCustomFieldValue') - > getFieldValue($ filters);
if($ DbCustomFieldValue){
$ form [$ customField-> getFieldAlias()] - > setData($ DbCustomFieldValue-> getValue());
} else {
$ form [$ customField-> getFieldAlias()] - > setData(array());
}
}
}
}
}

问题是当我尝试编辑一个表单。如果你看看上面的代码中的问题在这里的部分,你可以理解。



如果表单的对象有一个ID,那么我会获取为该对象的自定义字段存储的值,我调用$ form [field_alias'] - > setData(从数据库返回的值,映射为类型Array)。



但是这不工作,并且数据没有设置为字段。但是如果在我的控制器中我也是这样做的,数据设置正确。



有没有人知道这个问题可以吗?我不能在preSetData事件中设置数据?



EDITED



实体DbCustomField的值字段以这种方式映射:

  / ** 
* @var string
*
* @ ORM\Column(name =value,type =array,nullable = true)
* /
protected $ value;

`



var_dump($ DbCustomFieldValue) - >对象(Ueb\Core\Bundle\SchemaBundle\Entity\DbCustomFieldValue)

  var_dump(DbCustomFieldValue-> getValue())

- > string (11)bruno valor



但即使我尝试像:



var_dump($ customField-> getFieldAlias()); = string(21)testebruno-1383147874



$ form [$ customField-> getFieldAlias()] - > setData('example1'); 它不工作。



但是在我的控制器中,如果我对上面的字段执行以下操作:

  $ form ['testebruno-1383147874']  - > setData ( '例2'); 

- >它工作



任何想法?

解决方案

作为


In my Application the user can create Custom Fields for some entities and then set the values for this custom fields for each entity object when i display a form.

The implementation is like this:

1º) I created a Interface for the forms, and the forms that i want implement this Interface.

2º) I created a form extension for all forms:

app_core_form_builder.form_extension:
        class: App\Core\Bundle\FormBuilderBundle\Form\FormExtension
        arguments: ["@service_container", "@doctrine.orm.entity_manager"]
        tags:
            - { name: form.type_extension, alias: form }

3º) In this extension if the form implements the interface referenced in the step 1 i add a EventSubscriber:

if($formType instanceof \App\Core\Bundle\FormBuilderBundle\Model\IAllowCustomFieldsdInterface){
             $builder->addEventSubscriber(new FormSubscriber($this->container, $this->em));    
}

4º) This Form Subscriber subscribes the preSetData FormEvent. In this method i get the Entity associated with the form and i get all custom fields created for it. Then i add this fields to the form with the help of Symfony2 Form Type. Everything goes well, and when i display my form the custom fields are rendered correct. Just for the record, when i save the form the values inserted in the custom fields also are store well.

public function preSetData(FormEvent $event) {

        $data = $event->getData();
        $form = $event->getForm();


        // During form creation setData() is called with null as an argument
        // by the FormBuilder constructor. You're only concerned with when
        // setData is called with an actual Entity object in it (whether new
        // or fetched with Doctrine). This if statement lets you skip right
        // over the null condition.
        if (null === $data) {
            return;
        }

        $formEntity = $form->getConfig()->getType()->getInnerType()->getEntity();

        $DbEntity = $this->em->getRepository('AppCoreSchemaBundle:DbEntity')->findOneBy(array('id' => $formEntity));

        if ($DbEntity && $DbEntity->getAllowCustomFields()) {

            $organization = $this->container->get('app_user.user_manager')->getCurrentOrganization();

            if (!$organization) {
                throw $this->createNotFoundException('Unable to find Organization entity.');
            }

            $params = array(
                'organization' => $organization,
                'entity' => $DbEntity,
            );

            $entities = $this->em->getRepository('AppCoreSchemaBundle:DbCustomField')->getAll($params);


            # RUN BY ALL CUSTOM FIELDS AND ADD APPROPRIATE FIELD TYPES AND VALIDATORS
            foreach ($entities as $customField) {
                # configurate customfield

                FieldConfiguration::configurate($customField, $form);
                # THE PROBLEM IS HERE
                # IF OBJECT IS NOT NULL THEN MAKE SET DATA FOR APPROPRIATED FIELD
                if ($data->getId()) {

                    $filters = array(
                        'custom_field' => $customField,
                        'object' => $data->getId(),
                    );

                    $DbCustomFieldValue = $this->em->getRepository('UebCoreSchemaBundle:DbCustomFieldValue')->getFieldValue($filters);
                if ($DbCustomFieldValue) {
                    $form[$customField->getFieldAlias()]->setData($DbCustomFieldValue->getValue());
                } else {
                    $form[$customField->getFieldAlias()]->setData(array());
                }
                }
            }
        }
    }

The problem is when i try to edit a form. if you look at the part in the code above where says "THE PROBLEM IS HERE" you can understand.

If the object of the form has an ID, then i will get the values stored for the custom fields of that object, and i call $form[field_alias']->setData(value returned from database that is mapped as type Array).

But this dont work, and the Data is not set for the fields. But if in my controller i do the same, the data is set properly.

Does anybody have an idea where the problem can be? Can't i set the data in preSetData Event?

EDITED

The value field from the Entity DbCustomField is mapped in this way:

/**
     * @var string
     *
     * @ORM\Column(name="value", type="array", nullable=true)
     */
    protected $value;

`

var_dump($DbCustomFieldValue) -> object(Ueb\Core\Bundle\SchemaBundle\Entity\DbCustomFieldValue)

var_dump(DbCustomFieldValue->getValue())

-> string(11) "bruno valor"

But even if i try something like:

var_dump($customField->getFieldAlias()); = string(21) "testebruno-1383147874"

$form[$customField->getFieldAlias()]->setData('example1'); it doesnt work.

But in my controller if i do the following for the fieldAlias above:

$form['testebruno-1383147874']->setData('example2');

-> it does work

Any idea?

解决方案

As metalvarez suggested in his/her comment and working as expected, use the postSetData event instead of the preSetData one:

public function postSetData(FormEvent $event) {
    // ...
}

The preSetData event method is called before populating the form with default values, then Symfony2 will set the data and it may change from what you set before, thus the use of postSetData instead.

Figure from the doc

这篇关于Symfony2 Form Event PreSetData Subscriber的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆