現在、私のアプリケーションは this answer で推奨されているように、コンストラクターを使用してフォームタイプにデータを渡します。ただし、 Symfony 2.8アップグレードガイド は、型インスタンスをcreateForm
関数に渡すことは非推奨であるとアドバイスしています。
型インスタンスをForm :: add()、FormBuilder :: add()およびFormFactory :: create *()メソッドに渡すことは非推奨であり、Symfony 3.0ではサポートされなくなりました。代わりに、型の完全修飾クラス名を渡します。
Before: $form = $this->createForm(new MyType()); After: $form = $this->createForm(MyType::class);
完全修飾クラス名でデータを渡すことができないのを見て、代替手段はありますか?
これにより、フォームの一部も破損しました。オプションリゾルバーにカスタムデータを渡すことで修正しました。
フォームの種類:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->traitChoices = $options['trait_choices'];
$builder
->add('name', TextType::class, ['label' => 'L_PROFILE_EDIT_NAME', 'required' => false])
...
->add('figure_type', ChoiceType::class, [
'label' => 'L_PROFILE_EDIT_FIGURETYPE',
'mapped' => false,
'choices' => $this->traitChoices['figure_type']
])
...
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Foo\BarBundle\Entity\Profile',
'trait_choices' => null,
));
}
次に、コントローラーでフォームを作成するときに、コンストラクターではなくオプションとしてフォームを渡します。
$form = $this->createForm(ProfileEditType::class, $profile, array(
'action' => $this->generateUrl('profile_update'),
'method' => 'PUT',
'trait_choices' => $traitChoices,
));
ここで別のアプローチを使用できます-データを取得するためのサービスを注入します。
例:
services:
app.any.manager:
class: AppBundle\Service\AnyManager
form.my.type:
class: AppBundle\Form\MyType
arguments: ["@app.any.manager"]
tags: [ name: form.type ]
<?php
namespace AppBundle\Form;
use AppBundle\Service\AnyManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class MyType extends AbstractType {
/**
* @var AnyManager
*/
protected $manager;
/**
* MyType constructor.
* @param AnyManager $manager
*/
public function __construct(AnyManager $manager) {
$this->manager = $manager;
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$choices = $this->manager->getSomeData();
$builder
->add('type', ChoiceType::class, [
'choices' => $choices
])
;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\MyData'
]);
}
}
Symfony 3を使用しているユーザーのために、データを埋め込みフォームに渡す方法は次のとおりです。まず、上記の@seklで説明したことを正確に実行してから、次の操作を実行します。
プライマリFormTypeで
' entry_options 'を使用してvarを埋め込みフォームに渡します
->add('your_embedded_field', CollectionType::class, array(
'entry_type' => YourEntityType::class,
'entry_options' => array(
'var' => $this->var
)))
埋め込みFormTypeで
OptionsResolverにオプションを追加します
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Yourbundle\Entity\YourEntity',
'var' => null
));
}
BuildForm関数の変数にアクセスします。ビルダー関数の前にこの変数を設定することを忘れないでください。私の場合、特定のIDに基づいてオプションをフィルタリングする必要がありました。
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->var = $options['var'];
$builder
->add('your_field', EntityType::class, array(
'class' => 'YourBundle:YourClass',
'query_builder' => function ($er) {
return $er->createQueryBuilder('u')
->join('u.entity', 'up')
->where('up.id = :var')
->setParameter("var", $this->var);
}))
;
}
誰かがform.factoryサービスの「createNamedBuilder」または「createNamed」関数を使用している場合、それを使用してデータを設定および保存する方法のスニペットがあります。 'data'フィールドを使用することはできません(そのnullのままにします)。渡されたデータ/エンティティを$options
値として設定する必要があります。
また、setAllowedTypes()およびsetRequired()オプションの使用に関する@sarahgの指示を組み込みましたが、うまくいくようですが、最初にsetDefined()でフィールドを定義する必要があります
また、データを設定する必要がある場合は、フォーム内で「データ」フィールドに追加することを忘れないでください。
コントローラーでは、getNameが2.8/3.0で非推奨になったため、getBlockPrefixを使用しています。
コントローラ:
/*
* @var $builder Symfony\Component\Form\FormBuilderInterface
*/
$formTicket = $this->get('form.factory')->createNamed($tasksPerformedForm->getBlockPrefix(), TaskAddToTicket::class, null, array('ticket'=>$ticket) );
形:
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefined('ticket');
$resolver->setRequired('ticket');
$resolver->addAllowedTypes('ticket', Ticket::class);
$resolver->setDefaults(array(
'translation_domain'=>'AcmeForm',
'validation_groups'=>array('validation_group_001'),
'tasks' => null,
'ticket' => null,
));
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$this->setTicket($options['ticket']);
//This is required to set data inside the form!
$options['data']['ticket']=$options['ticket'];
$builder
->add('ticket', HiddenType::class, array(
'data_class'=>'acme\TicketBundle\Entity\Ticket',
)
)
...
}