Php Symfony 2设置嵌入式实体表单数据

Php Symfony 2设置嵌入式实体表单数据,php,jquery,ajax,forms,symfony,Php,Jquery,Ajax,Forms,Symfony,目前,我在表单中嵌入了实体表单。我希望在用户选择项目时,底层数据能够自动填充地址字段。但是,使用实体中如下所示的表单事件和Symfony 2文档中指定的相应ajax代码,地址字段永远不会填充到相应的ajax响应中 使用var_dump,我可以看到在添加address字段时,地址被抓取并发送到data选项。但是,当表单仅与所选项目一起提交时,它永远不会显示在表单响应中 这是正确的方法还是我遗漏了一些重要的部分?或者symfony不这样做,我应该通过jquery/ajax这样做吗 交易用户 clas

目前,我在表单中嵌入了实体表单。我希望在用户选择项目时,底层数据能够自动填充地址字段。但是,使用实体中如下所示的表单事件和Symfony 2文档中指定的相应ajax代码,地址字段永远不会填充到相应的ajax响应中

使用var_dump,我可以看到在添加address字段时,地址被抓取并发送到data选项。但是,当表单仅与所选项目一起提交时,它永远不会显示在表单响应中

这是正确的方法还是我遗漏了一些重要的部分?或者symfony不这样做,我应该通过jquery/ajax这样做吗

交易用户

class TransactionUser
{
    /**
     * @var string
     *
     * @ORM\Column(name="id", type="guid")
     * @ORM\Id
     */
    private $id;

    /**
     * The associated transaction to this TransactionUser.
     *
     * @var \Acme\BaseBundle\Entity\Transaction $transaction
     *
     * @ORM\ManyToOne(targetEntity="Acme\BaseBundle\Entity\Transaction", inversedBy="transactionUsers", cascade={"all"})
     */
    private $transaction;

    /**
     * The Project that this TransactionUser is associated with.
     *
     * @var \Acme\BaseBundle\Entity\Project
     *
     * @ORM\ManyToOne(targetEntity="Acme\BaseBundle\Entity\Project", inversedBy="transactionUsers", cascade={"all"})
     */
    private $project;
}
交易

class Transaction
{
    /**
     * @var string
     *
     * @ORM\Column(name="id", type="guid")
     * @ORM\Id
     */
    private $id;

    /**
     * @var \Acme\BaseBundle\Entity\Address
     *
     * @ORM\ManyToOne(targetEntity="Acme\BaseBundle\Entity\Address", cascade={"persist"}, inversedBy="propertyAddressTransactions")
     */
    private $propertyAddress;


    /**
     * @ORM\OneToMany(targetEntity="Acme\BaseBundle\Entity\TransactionUser", mappedBy="transaction", cascade={"all"})
     */
    private $transactionUsers;

}
地址

class Address
{
    /**
     * The database id for the Address.
     *
     * @var string
     *
     * @ORM\Column(name="id", type="guid")
     * @ORM\Id
     */
    private $id;

    /**
     * The first line of the street address.
     *
     * @var string
     *
     * @ORM\Column(name="streetAddressLine1", type="text")
     */
    private $streetAddressLine1;

    /**
     * The Transactions that list this address as the property address.
     *
     * @ORM\OneToMany(targetEntity="Acme\BaseBundle\Entity\Transaction", mappedBy="propertyAddress")
     */
    private $propertyAddressTransactions;
}
项目

class Project
{
    /**
     * @var string
     *
     * @ORM\Column(name="id", type="guid")
     * @ORM\Id
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="Acme\BaseBundle\Entity\TransactionUser", mappedBy="project", cascade={"all"})
     * \Doctrine\Common\Collections\ArrayCollection
     */
    private $transactionUsers;

}
NewTransactionFormType

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

        $builder->add('project', EntityType::class, array(
                'class' => 'AcmeBaseBundle:Project',
                'required' => false,
                'optional' => true,
                'label' => 'Select Project',
                'placeholder' => 'Select Project',
                'property' => 'projectName',
                'query_builder' => function (EntityRepository $er) {
                    $queryBuilder = $er->createQueryBuilder('p');
                    return $queryBuilder;
                },
        ));

        $builder->add('transaction', NewTransactionSubFormType::class);

        $builder->get('transaction')->add('propertyAddress', AddressFormType::class);

        //Listeners on project to set the address
        $formModifier = function (FormInterface $form, Project $project = null) {
            $address = null;

            if (!is_null($project) && !is_null($project->getId())) {
                $address = $project->getFirstTransactionAddress();
            }

            $form->get('transaction')->add('propertyAddress', AddressFormType::class, array(
                'data' => $address
            ));
        };

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {
                // this would be your entity, i.e. Transaction
                $data = $event->getData();

                $formModifier($event->getForm(), $data->getProject());
            }
        );

        $builder->get('project')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {
                // It's important here to fetch $event->getForm()->getData(), as
                // $event->getData() will get you the client data (that is, the ID)
                $project = $event->getForm()->getData();

                // since we've added the listener to the child, we'll have to pass on
                // the parent to the callback functions!
                $formModifier($event->getForm()->getParent(), $project);
            }
        );

    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BaseBundle\Entity\TransactionUser',
        ));
    }
}
class NewTransactionSubFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', TextType::class, array(
            'label' => 'Name',
            'attr' => array(
                'class' => '',
                'placeholder' => 'Name',
            ),
            'required' => true,
        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BaseBundle\Entity\Transaction',
        ));
    }
}
class AddressFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('streetAddressLine1', TextType::class, array(
            'label' => 'Street Address Line 1',
            'attr' => array(
                'class' => '',
                'placeholder' => 'Street Address Line 1',
            ),
            'required' => true,
        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BaseBundle\Entity\Address',
        ));
    }
}    
NewTransactionSubFormType

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

        $builder->add('project', EntityType::class, array(
                'class' => 'AcmeBaseBundle:Project',
                'required' => false,
                'optional' => true,
                'label' => 'Select Project',
                'placeholder' => 'Select Project',
                'property' => 'projectName',
                'query_builder' => function (EntityRepository $er) {
                    $queryBuilder = $er->createQueryBuilder('p');
                    return $queryBuilder;
                },
        ));

        $builder->add('transaction', NewTransactionSubFormType::class);

        $builder->get('transaction')->add('propertyAddress', AddressFormType::class);

        //Listeners on project to set the address
        $formModifier = function (FormInterface $form, Project $project = null) {
            $address = null;

            if (!is_null($project) && !is_null($project->getId())) {
                $address = $project->getFirstTransactionAddress();
            }

            $form->get('transaction')->add('propertyAddress', AddressFormType::class, array(
                'data' => $address
            ));
        };

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {
                // this would be your entity, i.e. Transaction
                $data = $event->getData();

                $formModifier($event->getForm(), $data->getProject());
            }
        );

        $builder->get('project')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {
                // It's important here to fetch $event->getForm()->getData(), as
                // $event->getData() will get you the client data (that is, the ID)
                $project = $event->getForm()->getData();

                // since we've added the listener to the child, we'll have to pass on
                // the parent to the callback functions!
                $formModifier($event->getForm()->getParent(), $project);
            }
        );

    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BaseBundle\Entity\TransactionUser',
        ));
    }
}
class NewTransactionSubFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', TextType::class, array(
            'label' => 'Name',
            'attr' => array(
                'class' => '',
                'placeholder' => 'Name',
            ),
            'required' => true,
        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BaseBundle\Entity\Transaction',
        ));
    }
}
class AddressFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('streetAddressLine1', TextType::class, array(
            'label' => 'Street Address Line 1',
            'attr' => array(
                'class' => '',
                'placeholder' => 'Street Address Line 1',
            ),
            'required' => true,
        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BaseBundle\Entity\Address',
        ));
    }
}    
AddressFormType

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

        $builder->add('project', EntityType::class, array(
                'class' => 'AcmeBaseBundle:Project',
                'required' => false,
                'optional' => true,
                'label' => 'Select Project',
                'placeholder' => 'Select Project',
                'property' => 'projectName',
                'query_builder' => function (EntityRepository $er) {
                    $queryBuilder = $er->createQueryBuilder('p');
                    return $queryBuilder;
                },
        ));

        $builder->add('transaction', NewTransactionSubFormType::class);

        $builder->get('transaction')->add('propertyAddress', AddressFormType::class);

        //Listeners on project to set the address
        $formModifier = function (FormInterface $form, Project $project = null) {
            $address = null;

            if (!is_null($project) && !is_null($project->getId())) {
                $address = $project->getFirstTransactionAddress();
            }

            $form->get('transaction')->add('propertyAddress', AddressFormType::class, array(
                'data' => $address
            ));
        };

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {
                // this would be your entity, i.e. Transaction
                $data = $event->getData();

                $formModifier($event->getForm(), $data->getProject());
            }
        );

        $builder->get('project')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {
                // It's important here to fetch $event->getForm()->getData(), as
                // $event->getData() will get you the client data (that is, the ID)
                $project = $event->getForm()->getData();

                // since we've added the listener to the child, we'll have to pass on
                // the parent to the callback functions!
                $formModifier($event->getForm()->getParent(), $project);
            }
        );

    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BaseBundle\Entity\TransactionUser',
        ));
    }
}
class NewTransactionSubFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', TextType::class, array(
            'label' => 'Name',
            'attr' => array(
                'class' => '',
                'placeholder' => 'Name',
            ),
            'required' => true,
        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BaseBundle\Entity\Transaction',
        ));
    }
}
class AddressFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('streetAddressLine1', TextType::class, array(
            'label' => 'Street Address Line 1',
            'attr' => array(
                'class' => '',
                'placeholder' => 'Street Address Line 1',
            ),
            'required' => true,
        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BaseBundle\Entity\Address',
        ));
    }
}