Symfony2 表单事件 PreSetData 订阅者

2024-04-11

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

实现是这样的:

1°)我为表单创建了一个接口,并且我想要实现该接口的表单。

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

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°) 在此扩展中,如果表单实现了步骤 1 中引用的接口,我将添加一个 EventSubscriber:

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

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

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());
                }
                }
            }
        }
    }

问题是当我尝试编辑表单时。如果你看看上面代码中“问题就在这里”的部分,你就能理解了。

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

但这不起作用,并且未为字段设置数据。但如果在我的控制器中我执行相同的操作,则数据设置正确。

有人知道问题出在哪里吗?我不能在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())

-> 字符串(11)“布鲁诺·勇敢”

但即使我尝试类似的事情:

var_dump($customField->getFieldAlias());=字符串(21)“testebruno-1383147874”

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

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

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

-> 它确实有效

任何想法?


As 梅塔瓦雷斯 https://stackoverflow.com/users/1978737/metalvarez建议在他/她的评论中 https://stackoverflow.com/questions/19691951/symfony2-form-event-presetdata-subscriber?rq=1#comment29312371_19691951 and 按预期工作 https://stackoverflow.com/questions/19691951/symfony2-form-event-presetdata-subscriber?rq=1#comment29450255_19691951, 使用postSetData事件而不是preSetData one:

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

The preSetData在使用默认值填充表单之前调用 event 方法,然后 Symfony2 将设置数据,并且它可能会与您之前设置的内容发生变化,因此使用postSetData反而。

Figure 来自文档 http://symfony.com/doc/current/components/form/form_events.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Symfony2 表单事件 PreSetData 订阅者 的相关文章

随机推荐