无法将选项传递给嵌入式子表单?? $options 可以达到 sub-forms 吗? (不是 Collection)

Cannot pass options to embedded subforms?? Can $options get to sub-forms? (Not a Collection)

我在 Symfony 6 中动态 生成表单。我在控制器中调用传统方法中的表单类型 class。其中,我根据传递给 FormType class.

$options 的元素动态构建一些表单字段
<?php
    public function index(Request $request): Response
    {

    // Entity is called Breed
    $data = new Breed();

    // I am passing these $options to the form
    $options = [
            'form_1'          => true,
            'form_2'          => false,
            'units'           => 'pounds'
            'form_3'          => false,
        ];

    $form = $this->createForm(BreedSurveyType::class, $data, $options);
    
?>

在 BreedSurveyType 表单 class 中,我能够在 configureOptions 方法中声明它们的地方获取我的变量...

<?php
 public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Breed::class,
            'form_1'          => false,
            'form_2'          => false,
            'units'           => null
            'form_3'          => false,
        ]);
    }
?>

在 buildForm 方法中,我可以访问 $options,但如果我嵌入 sub-form.

则不能
<?php
 public function buildForm(FormBuilderInterface $builder,array $options): void 
{
        // form_1          =   true
        // form_2          =   false
        // units           =  'pounds'
        // form_3          =   true

        if ($options['form_1'] === true) {
            
            $builder
                ->add(
                    'name',
                    AnimalNameType::class
                );
        }

        if ($options['form_2'] === true) {
            
            $builder
                ->add(
                    'sex',
                    AnimalSexType::class
                );
        }

        if ($options['form_3'] === true) {
            
            $builder
                ->add(
                    'weight',
                    AnimalWeightType::class
                );
        }
?>

.. 在 parent-form 中,当我转储 $options 变量时,

array:59 [▼
  // snippet from web debug toolbar
  "form_1" => true
  "form_2" => false
  "units"  => "pounds"
  "form_3" => true
]

..... 在 sub-form 中,当我转储 $options 变量时,我从我在 configureOptions 方法中所做的声明中得到结果。

array:59 [▼
  // snippet from web debug toolbar
  "form_1" => false
  "form_2" => false
  "units"  => null
  "form_3" => false
]

实际上,是否有一种方法可以将 $options 传递给子表单,或者我是否需要在我的 BreedSurveyType class 中隔离动态创建表单的逻辑?

您可以在添加 属性 时将所需数据传递到 child 表单,方法是在选项中传递它。

您的 parent 表单:

class BreedType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        if ($options['form_1'] === true) {

            $builder
                ->add('name',AnimalNameType::class, [
                        'form_1' => $options['form_1'],
                        'form_2' => $options['form_2'],
                        'units' => $options['units'],
                        'form_3' => $options['form_2'],
                    ]

                );
        }

    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Breed::class, 
            "form_1" => true,
            "form_2" => false,
            "units"  => "pounds",
            "form_3" => true,
        ]);
    }

}

并在你的 child 表单中 AnimalNameType 指定 configureOptions

中的默认值
public function configureOptions(OptionsResolver $resolver): void
{
    $resolver->setDefaults([
        'data_class' => AnimalName::class,
        "form_1" => true,
        "form_2" => false,
        "units"  => "pounds",
        "form_3" => true,
    ]);
}

为了跟进上面 Harvi Dent 先生给出的答案,我使用以下技术找到了一个全局解决方法。 谢谢 Dent 先生.

  1. 我将所有默认 $options 放入具有 public(静态)数组的服务 class 中。在那个数组中,它只包含我将从 parent-form 传递到 sub-form.
  2. 的默认变量
  3. 调用 array_intersect_key() 函数

我服务中的常量(数组):

<?php
    public const DEFAULT_ASSESSMENT_OPTIONS
        = [
            'form_1'          => false,
            'form_2'          => false,
            'form_3'          => false,
            'units'           => 'pounds',
        ];
?>

修订技术

<?php
class ParentFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $newOptions = array_intersect_key($options, Options::DEFAULT_ASSESSMENT_OPTIONS);

        // Herein, I am just passing the new $options array, after 
        // I have removed all of the other $options passed into the 
        // original $options array and all of the other Symfony $options 
        // are removed.
        if ($newOptions['form_1'] === true) {
            $builder->add(
                'transferee',
                SubFormOneType::class,
                $newOptions   // array from above
            );
        }
}
?>