Symfony嵌入式表单的问题

时间:2015-08-31 04:58:02

标签: forms symfony doctrine entities

我正在尝试实现以下方案:

拍卖和类别实体(多对一)。 Category实体与CategoryAttribute实体具有一对多关系,允许将不同数量的各种类型的属性添加到类别中。假设一个Cars类别将具有Make和Year属性。 CategoryAttribute实体具有widgetType属性,该属性定义如何呈现属性(输入,选择等),attributeValues是属性的数据(填充选择等)和isRequired属性以告知属性是否是必需的。到现在为止还挺好。管理属性是件小事,但是:

在拍卖方面,当用户从列表中选择给定类别以呈现该类别的所有属性时,我想要的东西。这被转换为相关的AuctionAttribute实体(多对一到在类中的属性属性拍卖)。 AuctionAttribute引用了CategoryAttribute,一个attributeValue来保存输入或选定的值。

好吧,整个AJAX请求并填写所选类别的属性不是问题。提交表格时会出现问题。基本上有两个问题。

  1. 我们如何将表单的属性部分绑定到实际表单以进行验证。假设我们选择了Car类别,并且需要Make属性,我们如何验证此属性?

  2. 我们如何将该输入的属性输入绑定到AuctionAttribute实体?

  3. 我知道对于嵌入式表单我需要连接到FormEvents :: PRE_SUBMIT事件,但我不知道如何将属性转换为实体。

    就代码而言,我有以下内容:

    1. 获取类别的属性时,我创建AuctionAttributeFormType并将其呈现为twig形式的帮助器,并在AJAX请求中返回HTML:

      $form = $this->createForm(new Type\AuctionAttributeFormType(), null, array('csrf_protection' => false));
      
      foreach ($categoryAttributes as $attribute) {
          $form->add('attribute_'.$attribute->getId(), $attribute->getWidgetType(), array('label' => $attribute->getName(), 'required' => $attribute->isRequired());
      }
      
    2. 当提交拍卖表格时,我挂钩到PRE_SUBMIT事件以及是否有提交的属性并且它属于该类别的属性集,但这是我在被卡住之前所做的一切:

        $builder->addEventListener(
           Form\FormEvents::PRE_SUBMIT, function (Form\FormEvent $event) {
             $auction = $event->getData();
      
                if (null !== $auction['category']) {
                $categoryAttributes = $this
                        ->repository
                        ->findAttributesForCategory($auction['category'])
                        ->getResult();
      
                if (count($categoryAttributes) > 0) {
                    $attribute_values = array();
                    foreach ($categoryAttributes as $attribute) {
                        if (isset($auction['attribute_' . $attribute->getId()])) {
                            $attribute_values[$attribute->getId()] = $auction['attribute_' . $attribute->getId()];
                        }
                    }
                }
            }
        }
      );
      
    3. 我需要将来自attribute_values数组的值转换为绑定到Auction实体的AuctionAttribute实体。知道如何实现这一目标。我认为它应该通过某种数据转换器完成,但我不确定要转换哪些数据 - 它应该是一个form-> add字段,还是直接触摸填充数据的Auction实体。

      有什么建议吗?

      编辑:

      我使用了模型变换器,但现在还有另一个问题,在编辑记录时,如果有多个属性,则只有第一个填充数据。以下是代码的示例要点:

      https://gist.github.com/SvetlinStaev/86e066a865478e40718c

1 个答案:

答案 0 :(得分:1)

我的建议不是通过事件监听器转换提交的数据,而是使用数据转换器,您将其附加到表单字段,如下所示:

$formBuilder->add(
   $formBuilder
   ->create('FIELD_NAME', 'FIELD_TYPE', [
      ... FIELD_OPTIONS ...
   ])
   ->addModelTransformer(new SomeModelTransformer())
)

“SomeModelTransformer”类应该如下所示:

class SeatingToNumberTransformer implements DataTransformerInterface
{

    /**
     * Transforms the object from the norm data to model data
     * The norm data is the field value. Say you have an integer field, $normDataObject would be an int.
     * In your case: you need to instantiate several new AuctionAttribute objects and persist them maybe
     */
    public function transform($normDataObject)
    {
        $transformedObject = $this->someTransformAction($normDataObject);
        return $transformedObject;
    }



    /**
     * Reverts the transform
     * in your case: from AuctionAttribute to int 
     */
    public function reverseTransform($modelDataObject)
    {
        $transformedObject = $this->someOtherTransformAction($modelDataObject);
        return $transformedObject;
    }
}

可以找到更多信息here
如果您需要更多帮助,请告诉我。