web-dev-qa-db-ja.com

Symfony2-投稿データに存在しないフィールドをForm-> handleRequestがnullにしないようにする方法

Symfonyにフォームが組み込まれていて、ビューでレンダリングすると、htmlフォームにフォームオブジェクトのすべてのフィールドが含まれる場合と含まれない場合があります(エンティティの種類にはいくつかの異なる状態があり、すべてのフィールドがレンダリングされるわけではありません)景色)。

問題は、フォームが送信ハンドラーでフォームオブジェクトのhandleRequest()メソッドを介して処理されると、投稿データに存在しないエンティティ内のプロパティがnullにリセットされ、既存の値が吹き飛ばされることです。

Symfonyにそれほど愚かではなく、POSTデータに存在するフィールドのみを処理するように指示する方法はありますか?

または、handleRequest呼び出しの前にエンティティのクローンを作成してから、POST値をループし、関連する値をpost-handleRequestエンティティからエンティティのpre-handleRequestクローンにコピーする必要がありますか?したがって、POSTデータにないフィールドを保持します。

ふぅ!ご覧のとおり、ちょっとした問題に対するちょっとした解決策です、tbh。

エンティティが実際には新しく作成されたオブジェクトである場合、symfonyがこれを行うことは理解できましたが、DBからロードされ、handleRequestが呼び出されました-オブジェクトがすでに初期化されていることを認識し、渡されたフィールドのみを設定することは十分に賢明なはずですPOSTデータ。

助けてくれてありがとう。

よろしく

スティーブ。

23
Steve Childs

つまり、handleRequestは使用しないでください。

代わりに、submitパラメータをfalseに設定してclearMissingを直接使用する必要があります。

Symfony/Component/Form/FormInterface

_/**
 * Submits data to the form, transforms and validates it.
 *
 * @param null|string|array $submittedData The submitted data.
 * @param bool              $clearMissing  Whether to set fields to NULL
 *                                         when they are missing in the
 *                                         submitted data.
 *
 * @return FormInterface The form instance
 *
 * @throws Exception\AlreadySubmittedException If the form has already been submitted.
 */
public function submit($submittedData, $clearMissing = true);
_

handleRequestを使用すると、送信するデータが特定され、$form->submit($data, 'PATCH' !== $method);を使用して送信されます。つまり、PATCHメソッドを使用してフォームを送信していない限り、フィールドをクリアします。

使用できることをクリアせずに自分でフォームを送信するには...

_$form->submit($request->get($form->getName()), false);
_

..リクエストからフォームデータ配列を取得して直接送信しますが、clearmissingfieldsパラメーターはfalseに設定されています。

49
qooplmao

エンティティの状態が異なる場合は、これをフォームタイプに反映できます。

さまざまなフィールド設定を含む複数のフォームタイプを作成し(おそらく継承を使用)、コントローラーで必要なフォームタイプをインスタンス化します。

このようなもの:

class YourState1FormType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('someField')
        ;
    }

}

class YourState2FormType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('someOtherField')
        ;
    }

}

または、コントローラーでの作成時にパラメーターを単一のフォームタイプに渡し、状態に応じてフィールド設定を調整します。存在しないフィールドを追加しないと、それらは処理されません。

このようなもの:

class YourFormType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if($options['state'] == 'state1') {
            $builder
                ->add('someField')
            ;
        } else if($options['state'] == 'state2') {
            $builder
                ->add('someOtherField')
            ;
        }
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'state' => 'state1'
        ));
    }

}

更新

送信されたデータに基づいてフォームを変更するために使用できる別のアプローチは、イベントリスナーをフォームのPRE_SET_DATAイベントとPOST_SUBMITイベントに登録することです。これらのリスナーは、フォーム送信プロセス内のさまざまな時点で呼び出され、フォームの作成時にフォームタイプに渡されるデータオブジェクト(PRE_SET_DATA)またはユーザーによって送信されたフォームデータ(POST_SUBMIT)に応じてフォームを変更できます。

説明と例を見つけることができます ドキュメント内

3
janwschaefer