首页 > 解决方案 > Symfony3 将表单数据传递给集合内的集合

问题描述

我有一些带有 CollectionType 的嵌套表单,并且似乎来自构造函数的数据没有传递到第二个嵌套级别。

我简化了我的表单类,只是我认为很重要(如果您想了解更多信息,请在评论中告诉我)。

底层表单完全依赖Activity实体类生成:

class ActivityServiceCreationType extends AbstractType {
  public function buildForm(FormBuilderInterface $builder, array $options) {

    $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($options, $router) {
      $activity = $event->getData();
      dump($activity); //JUST TO TEST

      $form = $event->getForm();
      ... //$form->add of all necessary fields
    }
  }

  public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\Activity',
      ...
    );
  }
}

在 ActivityServiceCreationType 上,我有下一个表单,它只是前一个表单的集合:

class ActivityServiceCreationMultipleType extends AbstractType {

  public function buildForm(FormBuilderInterface $builder, array $options) {

    $builder
      ->add('activities', CustomCollectionType::class, [
        'entry_type'    => ActivityServiceCreationType::class,
        'entry_options' => $options,
        'mapped'        => true,
        'allow_add'     => true,
        'show_add_link' => true,
      ])
    ;

    $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($options) {
      $data = $event->getData();
      dump($data); //To test the data arriving to this form

    });
  }

  public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
      'data_class' => null,
      ...
    ));
  }
}

然后我有“主”表单,我从控制器创建:

class ActivityServiceCreationCollectionType extends AbstractType {
  public function buildForm(FormBuilderInterface $builder, array $options) {
  $builder
    ->add('selectAll', CheckboxType::class, [...])
    ...
  ;

  $builder->add('multipleActivities', CustomCollectionType::class, [
    'entry_type'    => ActivityServiceCreationMultipleType::class,
    'entry_options' => [
      "router"     => $options["router"],
      "em"         => $options['em'],
      "basePeriod" => $options['basePeriod'],
      'fit'        => $options['fit'],
      'periods'    => $options['periods'],
      'activities' => $options['activities']
    ],
    'mapped'        => true
    ])
  ;
}

从控制器中,我想将 Activity 对象设置为 ActivityServiceCreationType 表单,以便可以创建字段。我正在这样做:

$form = $this->createForm(ActivityServiceCreationCollectionType::class,
  ["multipleActivities" => ["activities" => $activities]],
  [
    "router"     => $this->get("router"),
    "em"         => $this->getEm(),
    "periods"    => $periods,
    "basePeriod" => $basePeriod,
    'fit'        => $fit
  ]);

如您所见,表单的数据是:

["multipleActivities" => ["activities" => $activities]]

我在代码中放入的转储结果如下: 对于第一个转储,在 ActivityServiceCreationMultipleType 中,我得到一个 ArrayCollection 的活动 在此处输入图像描述

女巫是预期的,这里没问题,

但是在第二个转储中,在 ActivityServiceCreationType 中,我得到了null。这里我期望的是集合中每个表单的 Activity 实体,对吧?

你能告诉我哪里错了吗?

-- 编辑添加更多信息:我一直试图知道数据何时“丢失”,并在集合类型的事件中添加了一些代码。在 ActivityServiceCreationMultipleType 中以这种方式更改了 POST_SET_DATA:

$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($options) {
  $data = $event->getData();
  dump($data);

  $form = $event->getForm();
  $form->get('activities')->setData($data);
});

现在,ActivityServiceCreationMultipleType 中的 dump()(您在最后一个代码片段中看到)显示了活动数组。直接活动。并且 ActivityServiceCreationType 中的 dump() 执行了 36 次(每个活动一次),并且为 null ...不知道为什么它似乎将数据传递给最后一个嵌入的表单,但事件无法获取它。

标签: phpsymfonydoctrinesymfony-3.1

解决方案


编辑

ActivityServiceCreationCollectionType 的配置选项必须是:

  public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
      'data_class' => null,
      'multipleActivities' => null
    );
  }

ActivityServiceCreationMultipleType 的 configureOptions。

public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
      'data_class' => null,
      'entry_options' => null,
      'router" => null,
      'em" => null,
      'basePeriod" => null,
      'fit' => null,
      'periods'=>null,
      'activities' => null
    ));
  }

ActivityServiceCreationType 的 configureOptions。

public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\Activity',
      'entry_options' => null,
      'router" => null,
      'em" => null,
      'basePeriod" => null,
      'fit' => null,
      'periods'=>null,
      'activities' => null
    ));
  }

总之,您必须始终在 configureOptions 中指明要传递给表单的每个外部属性


推荐阅读