草庐IT

php - Symfony2 表单事件 PreSetData 订阅者

coder 2024-04-20 原文

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

实现是这样的:

1º) 我为表单创建了一个接口(interface),我想要实现这个接口(interface)的表单。

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 中引用的接口(interface),我将添加一个 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(从映射为类型的数据库返回的值数组)。

但这不起作用,并且没有为字段设置数据。但如果在我的 Controller 中我也这样做,则数据设置正确。

有人知道问题出在哪里吗?我不能在 preSetData 事件中设置数据吗?

已编辑

实体 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) "布鲁诺英勇"

但即使我尝试这样的事情:

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

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

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

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

->它确实有效

有什么想法吗?

最佳答案

作为metalvarez建议in his/her commentworking as expected ,使用 postSetData 事件代替 preSetData 一个:

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

preSetData 事件方法在用默认值填充表单之前调用,然后 Symfony2 将设置数据,它可能会与您之前设置的不同,因此使用 postSetData 代替。

from the doc

关于php - Symfony2 表单事件 PreSetData 订阅者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19691951/

有关php - Symfony2 表单事件 PreSetData 订阅者的更多相关文章

  1. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  2. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  3. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  4. ruby-on-rails - 事件记录 : Select max of limit - 2

    我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

  5. ruby-on-rails - 事件管理员和自定义方法 - 2

    这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什

  6. ruby-on-rails - 在不重新查询数据库的情况下重新排序 Rails 中的事件记录? - 2

    例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果

  7. ruby-on-rails - Ruby 长时间运行的进程对队列事件使用react - 2

    我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby​​脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几

  8. ruby-on-rails - 使用 Rails 事件记录获取二级模型 - 2

    我有一个帖子属于城市的关系,城市又属于一个州,例如:classPost现在我想找到所有帖子及其所属的城市和州。我编写了以下查询来获取带有城市的帖子,但不知道如何在同一查找器中获取带有城市的相应州:@post=Post.find:all,:include=>[:city]感谢任何帮助。谢谢。 最佳答案 Post.all(:include=>{:city=>:state}) 关于ruby-on-rails-使用Rails事件记录获取二级模型,我们在StackOverflow上找到一个类似的问

  9. ruby-on-rails - 从 ActiveAdmin has_many 表单助手中删除 "Add new"按钮 - 2

    我在事件管理员编辑页面中有嵌套资源,但我只想允许管理员编辑现有资源的内容,而不是添加新的嵌套资源。我的代码看起来像这样:formdo|f|f.inputsdof.input:authorf.input:contentf.has_many:commentsdo|comment_form|comment_form.input:contentcomment_form.input:_destroy,as::boolean,required:false,label:'Remove'endendf.actionsend但它在输入下添加了“添加新评论”按钮。我怎样才能禁用它,并只为主窗体保留f.ac

  10. ruby - 在没有数据库的情况下伪造一个事件记录模型 - 2

    我觉得我错过了什么。我正在编写一个ruby​​gem,它允许与事件记录进行交互,作为其主要功能的附加功能。在为其编写测试用例时,我需要能够指定虚拟事件记录模型来测试此功能。如果我可以获得一个事件记录模型的实例,它不需要与数据库的任何连接,可以有关系,所有这些东西,但不需要我在数据库中设置表,那就太棒了。我对测试还很陌生,在Rails测试之外我也很陌生,但似乎我应该能够相当轻松地完成类似的事情,但我什么也没找到。谁能告诉我我错过了什么?我看过工厂、制造商、固定装置,所有这些似乎都想达到目标。人们如何在您只需要AR对象进行测试的地方测试gem? 最佳答案

随机推荐