Вложенные формы Symfony2: $options['data'] = null во вложенной форме?

Поскольку документация по этой теме несколько тонкая, я попал в тупик.

У меня есть две модели: Job и JobAttribute. У Job есть много JobAttribute, а у JobAttribute есть одно Job:

class Job {
    /**
     * @ORM\OneToMany(targetEntity="JobAttribute", mappedBy="job_attributes")
     *
     * @var ArrayCollection
     */
    private $attributes;
}

class JobAttribute {
    /**
    * @ORM\Column(name="type", type="string", length=50)
    * 
    * @var string
    */
    private $type;

    /**
    * @ORM\ManyToOne(targetEntity="Job", inversedBy="jobs")
    */
    private $job;

Теперь у меня есть следующий FormClass:

class JobType extends AbstractType {
    public function buildForm(FormBuilder $f, array $options) {
        $f->add('name', 'text');
        $f->add('attributes', 'collection', array('type' => new JobAttributeType()));
    }

    public function getName() {
        return 'job';
    }
}

class JobAttributeType extends AbstractType {
    public function buildForm(FormBuilder $f, array $options) {
        $attribute = $options['data'];
        $f->add('value', $attribute->getType());
    }

    public function getDefaultOptions(array $options) {
        return array('data_class' => 'JWF\WorkflowBundle\Entity\JobAttribute');
    }

    public function getName() {
        return 'job_attribute';
    }
}

Да, действительно, свойство type JobAttribute содержит тип поля Form, например. текст.

Итак, когда я вызываю FormBuilder для JobType в моем контроллере, $options['data'] правильно заполняется объектом Job-Object внутри JobType. Но вложенные $ options ['data'] вложенного JobAttributeType не указывают на объект JobAttribute. Это NULL.

В чем проблема? Где потеряна ассоциация? Почему $options['data'] = NULL во вложенных формах? Есть ли обходной путь для получения динамических типов полей (из Doctrine) во вложенной форме?

Заранее спасибо!

1 ответ

Вы не можете положиться на $options['data'] когда вы создаете форму, так как данные могут (и будут) изменяться в любое время после построения. Вместо этого вы должны использовать прослушиватели событий.

$formFactory = $builder->getFormFactory();
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formFactory) {
    $form = $event->getForm();
    $data = $event->getData();

    if ($data instanceof JobAttribute) {
        $form->add($formFactory->createNamed('value', $data->getType());
    }
});

Документация для этого может быть найдена в поваренной книге.

Другие вопросы по тегам