0

私は3日以上私を夢中にさせている問題に直面していて、解決策が見つかりません。それにもかかわらず、私が直面している問題とまったく同じスタックオーバーフローに関する投稿を見つけました。残念ながら、その人はなんとか解決策を見つけることができましたが、それを完全には共有していませんでした。彼が完全に説明したように、以下にコピーして貼り付けてください。
ちなみに、その投稿を作成した人は、この問題のアカウントを作成しただけで、他の理由で戻ってこなかったようです。だから私はここでもう一度尋ねることができます...

私には2つのエンティティ(AとB)があり、それらの間には多対1の関係があります。

Aエンティティを使用してフォームを作成し、エンティティフィールド(ドロップダウンリスト)を使用してBエンティティの行を表示します。クエリビルダーを使用してそれらをフィルタリングします。リストの値を変更しない場合(つまり、ajaxを使用する場合)、すべてが正常に機能しています。

しかし、ドロップダウンの値を動的に変更すると、フォームを送信すると、「この値は無効です」というエラーが表示されます。

これは、送信された値がクエリビルダーによって返される「配列」に含まれていないためです。

この検証は、エンティティフィールドのsymfonyでは自動的に行われるようです(このフィールドではアサートを使用しません)。これを取り除きたいのですが。しかし、どのように?

フォームイベントを実装する必要があるようです。残念ながらわかりません。私はその主題に関して非常に貧弱なドキュメントを読み、たくさんの投稿を読み、インターネットで検索しましたが、何も見つかりませんでした。

以下は私の個人的なフォームタイプです。私がしていることは次のとおりです。マップされたプロパティをfalseに設定して最初のエンティティフィールドタイプを作成し、部門を取得するためだけにエンティティをフィルタリングします。次に、ローカリゼーションと呼ばれる別のエンティティタイプを作成します。デフォルトでは、エンティティをフィルタリングして何も取得しません('')。次に、データを入力するために、Jqueryを使用します。しかし、残念ながら、私は他の仲間と同じ問題に悩まされています(上記を参照)。

use Symfony\Component\Form\FormBuilderInterface;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
use Doctrine\ORM\EntityRepository;
use Auth\GeoBundle\Form\LocalisationType;


class RegistrationFormType extends BaseType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);

        $builder->add('departement', 'entity', array(
            'mapped' => false,
            'empty_value' => '',
            'class' => 'AuthGeoBundle:Localisation',
            'property' => 'departement',
            'query_builder' => function ($repository) {
                return $repository
                    ->createQueryBuilder('e')
                    ->add('groupBy', 'e.departement')
                ;
            },
        ));


        $builder->add('localisation', 'entity', array(
            'empty_value' => '',
            'class' => 'AuthGeoBundle:Localisation',
            'property' => 'formLabel',
            'query_builder' => function ($repository) use ($dpt) {
                return $repository
                    ->createQueryBuilder('e')
                    ->where('e.departement = :dpt')
                    ->setParameter('dpt', '')
                    ->add('orderBy', 'e.ville ASC')
                ;
            },
        ));

        //some other fields here...
    }

    public function getName()
    {
        return 'auth_user_registration';
    }
}
4

2 に答える 2

2

私はついにフォームイベントを使用して解決策を見つけることができました。http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.htmlで「チュートリアル」を試して、動作させました:)誰かが興味を持った場合に使用したコードを以下に示します。

私のformType:

<?php
//src/Auth/UserBundle/Form/Type/RegistrationFormType.php
namespace Auth\UserBundle\Form\Type;

use Symfony\Component\Form\FormBuilderInterface;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
use Doctrine\ORM\EntityRepository;
use Auth\GeoBundle\Form\LocalisationType;

use Auth\UserBundle\Form\EventListener\IsAdminFieldSubscriber;

class RegistrationFormType extends BaseType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);

        //NE PAS EFFACER -> exempled e comment ajouter un champ qui n'a rien à voir avec nos entitys
        //$builder->add("firstName", "text", array("mapped" => false));

        $builder->add('departement', 'genemu_jqueryselect2_entity', array(
            'mapped' => false,
            'empty_value' => '',
            'class' => 'AuthGeoBundle:Localisation',
            'property' => 'departement',
            'query_builder' => function ($repository) {
                return $repository
                    ->createQueryBuilder('e')
                    ->add('groupBy', 'e.departement')
                ;
            },
        ));


        $dpt = "";
        $builder->add('localisation', 'genemu_jqueryselect2_entity', array(
            'empty_value' => '',
            'class' => 'AuthGeoBundle:Localisation',
            'property' => 'formLabel',
            'query_builder' => function ($repository) use ($dpt) {
                return $repository
                    ->createQueryBuilder('e')
                    ->where('e.departement = :dpt')
                    ->setParameter('dpt', $dpt)
                    ->add('orderBy', 'e.ville ASC')
                ;
            },
        ));

        $builder->add('sexe', 'genemu_jqueryselect2_choice', array(
            'empty_value' => '',
            'choices'   => array(
                'homme'   => 'Homme',
                'femme' => 'Femme',
            ),
            'configs' => array(
                'minimumResultsForSearch' => 5,
            )
        ));

        $builder->add('date_naissance', 'date', array(
            'empty_value' => '',
            'widget' => 'choice',
            'attr' => array('class' => 'input-small'),
            'years' => range(1900,2100),
            'months' => range(1,12),
            'days' => range(1,31),
        ));

        $builder->add('petit_mot');

        $subscriber = new IsAdminFieldSubscriber($builder->getFormFactory());
        $builder->addEventSubscriber($subscriber);
    }


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

私のEventListener:

<?php
//src/Auth/UserBundle/Form/EventListener/isAdminFieldSubscriber.php
namespace Auth\UserBundle\Form\EventListener;

use Symfony\Component\Form\Event\DataEvent;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;

class IsAdminFieldSubscriber implements EventSubscriberInterface
{
    /**
     * @var FormFactoryInterface 
     */
    private $factory;

    /**
     * @param FormFactoryInterface $factory 
     */
    public function __construct(FormFactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::PRE_BIND => 'preBind',
        );
    }

    /**
     * Called before form data is set
     *
     * @param DataEvent $event
     */
    public function preBind(DataEvent $event)
    {
        $data = $event->getData();
        $form = $event->getForm();

        if (null === $data) {
            return;
        }

        $dpt = $data['localisation'];

        $form->add($this->factory->createNamed('localisation', 'entity', null, array(
            'empty_value' => '',
            'class' => 'AuthGeoBundle:Localisation',
            'property' => 'formLabel',
            'query_builder' => function ($repository) use ($dpt)  {
                return $repository
                    ->createQueryBuilder('e')
                    ->where('e.id = :dpt_id')
                    ->setParameter('dpt_id', $dpt)
                    ->add('orderBy', 'e.ville ASC')
                ;
            },
        )));
    }

}
于 2013-01-22T22:39:32.737 に答える
0

あなたは自分で問題を説明します:

「送信された値が、クエリビルダーによって返される「配列」に含まれていないためです。」

この問題を解決するには、データトランスフォーマーを使用できます。

于 2013-01-22T14:58:55.160 に答える