简体   繁体   English

Symfony2:如何将使用工厂生成器创建的表单添加到另一个表单的集合类型字段中?

[英]Symfony2: How to add a form created using factory builder into another form's collection type field?

I am creating forms from yml at runtime. 我在运行时从yml创建表单。 I go through the elements in yml file and add appropriate fields to the form. 我浏览了yml文件中的元素,并将适当的字段添加到表单中。 The root form is created like this 根形式是这样创建的

$form = $factory->createBuilder("form", $this->userData);

The yml will have an option to define a collection field as well. yml还可以选择定义一个收集字段。 The collection field requires type option to be supplied which must be of type string , Symfony\\Component\\Form\\ResolvedFormTypeInterface , Symfony\\Component\\Form\\FormTypeInterface 收集字段需要提供type选项,该选项的类型必须是stringSymfony\\Component\\Form\\ResolvedFormTypeInterfaceSymfony\\Component\\Form\\FormTypeInterface

But since I am building the embedded form as well at runtime, I wont have a type and neither FormTypeInterface 但是由于我也在运行时也构建了嵌入式表单,因此我将没有类型,也没有FormTypeInterface

Here is the sample code of what I need to do 这是我需要做的示例代码

$options = isset($config["options"]) ? $config["options"]: [];
if ($config['type'] == 'collection') {
    $options['type'] = $this->buildForm($options['template'], $factory);
    unset($options['template']);
    $form->add($config["name"], $config["type"], $options);
}

Here $options['template'] is how the type for the embedded form is defined in yml file. 这里的$options['template']是如何在yml文件中定义嵌入表单的类型。 So that form is also build at runtime. 因此,该表单也在运行时生成。 How do I embed it in the root form? 如何将其嵌入根目录形式?

Edit: In fact, if I only have a single field, say email in the collection field, then it works fine. 编辑:实际上,如果我只有一个字段,请在“收集”字段中说出email ,那么它就可以正常工作。 But the yml spec will allow users to define multiple fields within collection fields. 但是yml规范将允许用户在集合字段中定义多个字段。 In symfony, this would be done by defining the embedded form type and setting type option of collection field type to that form type. 在symfony中,这将通过定义嵌入式表单类型并将集合字段类型的type选项设置为该表单类型来完成。 But how do I do it when creating forms at runtime? 但是在运行时创建表单时该怎么做?

I solved it by defining a form type class, that builds the form at runtime. 我通过定义一个窗体类型类来解决它,该类在运行时生成窗体。 The config(form design) is passed into the constructor and buildForm adds respective fields according to the design. config(form design)传递到构造函数中,并且buildForm根据设计添加相应的字段。

class RuntimeFormType extends AbstractType
{
    /**
     * @var string
     */
    private $name;

    /**
     * @var array
     */
    private $config;

    /**
     * RuntimeFormType constructor.
     * @param string $name
     * @param array $config
     */
    public function __construct($name, array $config)
    {
        $this->name = $name;
        $this->config = $config;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        foreach($this->config as $config){
            $options = isset($config["options"]) ? $config["options"]: [];

            if($config['type'] == 'image'){
                $options['data_class']  = null;
                $options['multiple']  = false;

                $options['attr'] = [
                    "accept" => "images/*"
                ];

                $builder->add($config["name"], "file", $options);
            }else{
                $builder->add($config["name"], $config["type"], $options);
            }
        }
    }


    public function getName()
    {
        return $this->name;
    }
}

and in the builder, when the type is collection type initialize this form type and add to the root form. 在构建器中,当类型为collection类型时,初始化此表单类型并添加到根表单中。

if ($config['type'] == 'collection') {
    $template = $options['template'];

    unset($options['template']);
    $options['type'] = new RuntimeFormType($config["name"], $template);

    $form->add($themeConfig["name"], $themeConfig["type"], $options);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM