2

我正在尝试创建一个具有来自 AttributeSet 的多个属性的产品表单。属性被分配给 AttributeSet,当加载产品表单时,所有分配的属性都将呈现在表单中,每个属性都有一个类型(文本、选项、单选等)

我不确定这是否是正确的方法(我确信有一种更清洁/更好的方法),但我是这样做的:

首先将 EventSubscriber 添加到主要 Product 表单类型

$builder->addEventSubscriber($this->buildProductAttributeFormListener)

在 EventSubscriber 我有 preSetData 事件:

public function preSetData(FormEvent $event)
{
    $product = $event->getData();
    $form = $event->getForm();

    if (null === $product->getAttributeSetId()) {
        // need to get attribute set id from request
        $request = Request::createFromGlobals()->get('rs_product_type_step');
        $attributeSetId = $request['attribute_set_id'];
        if (!$attributeSetId) {
            $request = Request::createFromGlobals()->get('rs_product');
            $attributeSetId = $request['attribute_set_id'];
        }
        // get assigned attribute set
        $attributeSet = $this->asRepository->find($attributeSetId);
    } else {
        $attributeSet = $product->getAttributeSetId();
    }

    // If product has attributes, lets add this configuration field.
    if ($attributeSet->hasAttributes()) {
        $form->add('attributes', 'rs_product_attribute_collection', array(
            'options'  => $attributeSet->getAttributes(),
            'required' => false
        ));
    }
}

在“rs_product_attribute_collection”类型中,我有这个 buildForm:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    // this loop adds each attribute as a field with his type (choice, text, etc...)   
    foreach ($options['options'] as $i => $attribute) {
        if (!$attribute instanceof AttributeInterface) {
            throw new LogicException('Each object passed as attribute must implement "AttributeInterface"');
        }

        $fieldOptions = array(
            'label' => $attribute->getName(),
        );

        if ($attribute->getType() == 'choice') {
            // add custom options for choice type
            //$fieldOptions = array_merge($fieldOptions, array('mapped' => false));
        }

        if (is_array($attribute->getOptions())) {
            $fieldOptions = array_merge($fieldOptions, $attribute->getOptions());
        }

        $builder->add($attribute->getId(), $attribute->getType(), $fieldOptions);
    }
}

现在我对这些有一些问题...... 1)我不确定这是否是正确的方法,因为 form->bind 没有正确绑定数据,所以我添加了 PRE_SUBMIT 事件来获取属性数据请求并手动将属性分配给产品。2) 验证为“选择”字段类型抛出“此值无效”错误消息。

我想听听如何使它工作的想法。

谢谢,罗恩。

4

1 回答 1

0

您还需要使 data_class 动态化,以便它使用您添加的属性集字段。

此外,请查看此处以获取有关如何使用表单事件动态修改表单的更多详细信息 http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

于 2013-08-14T13:47:23.107 回答