Symfony 2.8, 3.0 이상에서 buildForm ()에 데이터 전달
내 응용 프로그램은 현재이 답변 에서 권장하는 것처럼 생성자를 사용하여 내 양식 유형에 데이터를 전달합니다 . 그러나 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,
));
}
Then when you create the form in your controller, pass it in as an option instead of in the constructor:
$form = $this->createForm(ProfileEditType::class, $profile, array(
'action' => $this->generateUrl('profile_update'),
'method' => 'PUT',
'trait_choices' => $traitChoices,
));
Here can be used another approach - inject service for retrieve data.
- Describe your form as service (cookbook)
- Add protected field and constructor to form class
- Use injected object for get any data you need
Example:
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'
]);
}
}
In case anyone is using a 'createNamedBuilder' or 'createNamed' functions from form.factory service here's the snippet on how to set and save the data using it. You cannot use the 'data' field (leave that null) and you have to set the passed data/entities as $options
value.
I also incorporated @sarahg instructions about using setAllowedTypes() and setRequired() options and it seems to work fine but you first need to define field with setDefined()
Also inside the form if you need the data to be set remember to add it to 'data' field.
In Controller I am using getBlockPrefix as getName was deprecated in 2.8/3.0
Controller:
/*
* @var $builder Symfony\Component\Form\FormBuilderInterface
*/
$formTicket = $this->get('form.factory')->createNamed($tasksPerformedForm->getBlockPrefix(), TaskAddToTicket::class, null, array('ticket'=>$ticket) );
Form:
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',
)
)
...
}
Here's how to pass the data to an embedded form for anyone using Symfony 3. First do exactly what @sekl outlined above and then do the following:
In your primary FormType
Pass the var to the embedded form using 'entry_options'
->add('your_embedded_field', CollectionType::class, array(
'entry_type' => YourEntityType::class,
'entry_options' => array(
'var' => $this->var
)))
In your Embedded FormType
Add the option to the optionsResolver
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Yourbundle\Entity\YourEntity',
'var' => null
));
}
Access the variable in your buildForm function. Remember to set this variable before the builder function. In my case I needed to filter options based on a specific 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);
}))
;
}
참고URL : https://stackoverflow.com/questions/34027711/passing-data-to-buildform-in-symfony-2-8-3-0-and-above
'Programing' 카테고리의 다른 글
Android의 Chrome에서 실제 화면 크기 / dpi / 픽셀 밀도 가져 오기 (0) | 2020.09.22 |
---|---|
오류 : __karma __. start 메소드를 구현하는 일부 어댑터를 포함해야합니다. (0) | 2020.09.22 |
Vue-객체 배열을 깊이 관찰하고 변화를 계산합니까? (0) | 2020.09.22 |
.NET 목록 (0) | 2020.09.22 |
두 변수가 파이썬에서 동일한 객체를 참조하는지 비교 (0) | 2020.09.22 |