1

スポーツイベントの登録をする場合があります。

登録には、各スポーツに固有のいくつかのフィールドが含まれています。そのうちのいくつかは、スポーツごとに異なりますが、同じように名前が付けられます。例:「フィールド上のお気に入りの位置」:

バスケットボールの場合、次のいずれかの選択フィールドになります。

  • ポイントガード
  • シューティングガード
  • 等...

野球の場合、同じ選択フィールドになりますが、いくつかの異なる選択肢があります。

  • ピッチャー
  • 内野
  • 外野
  • ..。

(表示用の)フォームを最初に作成するとき、スポーツは登録のデータの一部として渡されます。

$registration = new Registration;
$registration->setEvent($event);

そして$event->getSport();そのイベントのためにスポーツを返すでしょう。

これまでのところ、フォームの生成にリスナーを追加すると、そのスポーツに固有のフィールドのみを設定できます。

public static function getSubscribedEvents()
{
    return [FormEvents::POST_SET_DATA => 'preSetData'];
}

/**
 * @param event DataEvent
 */
public function preSetData(DataEvent $event)
{
    $form = $event->getForm();

    if (null === $event->getData()) {
        return;
    }

    // (The get event here means the real life sports gathering)
    $sport = $event->getData()->getEvent()->getSport();
    /**
     * Then I customize the fields depending on the current sport
     */
}

問題は、ユーザーがこのフォームを送信し直すときに発生します。この場合、$event->getData()->getEvent()nullです。

「イベント」(実際のイベント)はdocument_id、登録フォームのフィールドです(ここではMongoDBを使用)。

::BINDの代わりにイベントを聞くと、::PRE_SET_DATAすべてにアクセスできますが、フォームはすでにバインドされているため、カスタマイズするには遅すぎます。::PRE_BINDと同じことをし::PRE_SET_DATAます。

フォームをカスタマイズして適切に検証するために、ここでイベントとスポーツのドキュメントを正しく取得するにはどうすればよいですか?

4

2 に答える 2

0

なぜそのようなタスクを実行するためにイベントが必要なのですか?buildForm()フォームクラスのアクションでフィールドを定義できます。イベントオブジェクトにアクセスするには、次のコマンドを使用します。$options['data']->getEvent()

于 2012-10-29T08:04:50.810 に答える
0

だから...最後にこれを正しく行う方法を見つけました。2つの異なるイベントにサブスクライブする必要があります。

フォームが最初に作成されると、一部のデータがフォームに渡されるため、PRE_SET_DATAイベントにはそのデータが含まれ、質問で説明されているようにすべてが正常に機能します。

フォームが送信された時点では、最初にデータなしで作成されるため、でアクセスされるデータはPRE_SET_DATAnullになります。この場合、フォームのカスタマイズをスキップします。

public function preSetData(DataEvent $event)
{
    $myEvent = $event->getData()->getEvent();

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

    $this->customizeForm();
}

これにより、フォームの送信時に問題が発生したり、データが渡されたりすることがなくなりますが、getData()NULLではなく空のオブジェクトが返されます。

これで、フォームが送信されたときに、受信したデータにフォームをバインドします。それが私たちが干渉したいときです。PRE_BINDそのため、イベントにも登録します。

public static function getSubscribedEvents()
{
    return [
        FormEvents::PRE_BIND => 'preBind',
        FormEvents::PRE_SET_DATA => 'preSetData',
    ];
}

事前バインドでは、受け取るデータは値の配列のみであり、オブジェクトグラフではありません。しかし、リスナーにオブジェクトマネージャーを挿入すると、オブジェクトを見つけて操作できます。

public function preBind(DataEvent $event)
{
    $data = $event->getData();
    $id = $data['event'];
    $myEvent = $this->om
                ->getRepository('Acme\DemoBundle\Document\Event')
                ->find(new \MongoId($id));
    if($myEvent === null){
        $msg = 'The event %s could not be found';
        throw new \Exception(sprintf($msg, $id));
    }

    $this->customizeForm();
}
于 2012-10-30T06:11:26.027 に答える