2017-03-25 28 views
2

Symfonyでのフォームに関するベストプラクティスはできるだけ多くのコードを再利用することです(おそらく一般的にはベストプラクティスです)。 エンティティを編集または作成するための一連のアクションを設定しました。両方のアクションで同じフォームクラスと同じ小枝テンプレートが使用されます。今私はそのエンティティの削除フォームを作成する必要があります。symfonyフォームのすべてのフィールドを動的に無効にする方法

エンティティの作成や編集に使用したテンプレートを再利用したいが、今回はすべてのフィールドが無効になる。この方法では、ユーザーはエンティティのコンテンツを表示しますが、フィールドを編集する機能によって混乱することはありません(送信ボタンをクリックすると、すべてが削除され、保存されません)。送信ボタンを含め、私が試した

// AppBundle/Controller/DeleteEntityController.php 
// ... 
class TermType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('term', TextType::class, array('label' => 'Term')); 
     $builder->add('definition', TextareaType::class, array('label' => 'Definition')); 
     $builder->add('visibility_status', ChoiceType::class, array(
       'label' => 'Visibility', 
       'choices' => array(
        'Visible' => true, 
        'Invisible' => false 
       ), 
      )); 
     $builder->add('page', EntityType::class, array(
       'label' => 'Page', 
       'class' => 'AppBundle:Page', 
       'query_builder' => function (PageRepository $er) { 
         return $er->getPageByType('Glossary'); 
       }, 
       'choice_label' => 'title' 
      )); 
     $builder->add('submit', SubmitType::class, array(
      'label' => 'Submit' 
     )); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => Term::class, 
     )); 
    } 
} 

まず最初に、フォームを呼び出すことだったと真($form = $this->createForm(TermType::class, $term, array('disabled' => true));)として無効に設定されますが、そのオプションはすべてを無効にします。

は今のところ、それはフォームクラスです。 は、だから私は明示的にそれがcreateFormに渡されたオプションをオーバーライドしているだろうと考え、送信ボタン有効:

// AppBundle/Form/TermType.php 
// ... 
$builder->add('submit', SubmitType::class, array(
      'label' => 'Submit', 
      'disabled' => false 
     )); 
// ... 

をしかし、それは動作しませんでした。私が考えることのできる唯一の選択肢は、カスタムオプションを渡して、すべてのフィールドにdisabledオプションを設定することですが、その値を持つ送信ボタンです。これらの線に沿って何か:

// AppBundle/Controller/DeleteEntityController.php 
// ... 
$form = $this->createForm(TermType::class, $term, array('is_delete_form' => true)); 
// ... 

// AppBundle/Form/TermType.php 
// ... 
$builder->add('submit', SubmitType::class, array(
     'label' => 'Submit', 
     'disabled' => $options['is_delete_form'] 
    )); 
// ... 

この場合のベストプラクティスは何ですか?テンプレート内のフィールドを無効にするか、フォームクラスから行う必要がありますか?

答えて

2

それは良い質問であり、あなたの解決策も賢明です。ちょうどあなたが追加のオプションを使用して行けば、それはconfigureOptions機能でのデフォルト値を設定することは常に良いことだことを覚えておいてください:

public function configureOptions(OptionsResolver $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => Term::class, 
     // Additional option default should be defined here 
    )); 
} 

しかし、あなたがベストプラクティスを検索する場合:Symfonyのからの提案が分離されますフォームクラスまたはコントローラからのボタン(コントローラでフォームを定義している場合)これにより、開発者はより柔軟に対応でき、フォームの操作がはるかに簡単になります。 Symfonyのアーキテクトがここで何を言っているのかは、http://symfony.com/doc/current/best_practices/forms.html#form-button-configurationです。

+0

私は同意します。 FormTypeクラスに送信ボタン(または他のボタン)を表示しないでください。代わりに、あなたがはるかに多くのコントロールを持っているあなたのテンプレートでレンダリングします。 – ehymel

+0

そのページを読んでいないと私は恥ずかしいです。テンプレートの中に送信ボタンを移動させた。コントローラーからテンプレートに送信されるパラメーター "action"は、正しいラベルとクラスを設定します。 現在、これが最適なソリューションです。しかし、私はまだいくつかのフォームフィールドがどのように使用されているかについて少し疑念を感じています。たとえば、私がChoiceTypeを使用するとき、選択肢として表示するかラジオボックスとして表示するかを選択できます。しかし、この選択肢は、フォームクラス内で表現とロジックを少し混ぜています。 – paratassi

+0

こんにちは@paratassi、フォームフィールドやフォームクラスのフォームにいくつかの属性を定義すると、それはまったく問題ありません。ロジックを完全に分離してForm Bundleで表示する方法はほとんどありません。しかし、Form Bundleのアイデアやデザインパターンはかなり古く、開発者は常にそれに固執する必要はないと私は信じています。 Reactのような最新のフロントエンドフレームワークでは、フロントエンド側で同じコードの再利用性と柔軟性を提供しますが、バックエンドでは、Formバインディングと同じことを実現するParams ConverterとValidatorの機能があります。 –

0

編集、作成、削除の設定に1つのフォームのみを使用するかどうかは、面白いことです。私のために、私はクラスのクルドを生成して時間を稼ぐために使用します。後で必要に合わせて調整できる、クラスの編集、作成、削除のフォーム、関数、ビューを直接取得できます。

あなたはCRUDが生成されると一つの形を得るだけに、彼らが使用するメソッドから自分のインスピレーションを描くことができます:

あなたがここで簡単に生成するための方法を持つことができます。http://symfony.com/doc/current/bundles/SensioGeneratorBundle/commands/generate_doctrine_crud.html

それは本当に答えていませんあなたの質問ですが、別の時間に役立つかもしれません;)

関連する問題