Параметр Symfony для ввода в buildForm - PullRequest
0 голосов
/ 29 августа 2018

Я использую Symfony <4, и у меня есть проблема с формой, использующей другую форму в отношении «Многие ко многим» с параметром. </p>

Вы найдете ниже моей FeatureForm:

            ->add('tags',CollectionType::class,
            array(
                'entry_type' =>TagFeatureType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'data' => $datas,
                'entry_options' => array(
                    'label' => false,
                )
            )
        )

Теперь мой TagFeatureType:

            ->add('tag', EntityType::class,
            array(
                'choice_label' => 'name',
                'class' => 'AppBundle:Tag',
                'query_builder' => function(TagRepository $tr){
                    return $tr->findObjectNotMine();
                }
            )
        )

Я хотел бы добавить параметр в findOBjectNotMine, но не могу передать параметр из контроллера, поскольку TagFeatureType создан FeatureForm. Внутри функции buildForm я не могу передать дополнительный параметр.

Я вижу 2 варианта, во-первых, я изменяю параметры по умолчанию, чтобы разрешить дополнительный параметр, но это немного отвратительно. Во-вторых, я мог бы использовать параметр сеанса и внедрить сервис сеанса внутри конструктора ... Но это выглядит скорее как обходной путь, чем как правильный путь ...

Знаете ли вы элегантный способ вставить параметр в форму из функции buildForm внутри FormType?

С наилучшими пожеланиями

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

В вашем TagFeatureType вы можете просто передать аргумент через инъекцию конструктора:

class TagFeatureType extends AbstractType
{
    private $tagRepository;

    public function __construct(TagRepository $tagRepository)
    {
        $this->tagRepository = $tagRepository;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $tr = $this->tagRepository;
        // ...
        ->add('tag', EntityType::class,
            array(
                'choice_label' => 'name',
                'class' => 'AppBundle:Tag',
                'query_builder' => function(TagRepository $tr){
                    return $tr->findObjectNotMine();
                }
            )
        )
    }
}

Существует расширение формы DependencyInjectionExtension , которое проверит, зарегистрирован ли тип формы в контейнере службы и затем внедрит его, вместо создания нового экземпляра. Это должно убедиться, что хранилище тегов существует.

0 голосов
/ 29 августа 2018

В случае, если вам нужно передать известные в контейнере параметры пользовательскому типу формы, вы можете пойти тем же путем, что и ранее (очевидно, через внедрение параметров). Однако, если вы хотите передать данные из контроллера в тип формы, вы можете передать их через $options (последний) аргумент (в buildForm):

FeatureForm

public function buildForm(FormBuilderInterface $builder, array $options)

    // ....

    $builder->add('tags', CollectionType::class, array (
           'entry_type' => TagFeatureType::class,
           'allow_add' => true,
           'allow_delete' => true,
           'data' => $datas,
           'entry_options' => array(
               'label' => false,
               'some_custom_param' => $options['some_custom_param']
           )
       )
    );

    // ....
 }

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

И тогда в TagFeatureType должны были быть настроены параметры:

TagFeatureType

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setRequired(array(
        'some_custom_param'
    ));
}

И, наконец, включите его в buildForm:

public function buildForm(FormBuilderInterface $builder, array $options)

    // ....
    $someCustomParam = $options['some_custom_param'];

    // .... 

    $builder->add('tag', EntityType::class, array(
        'choice_label' => 'name',
        'class' => 'AppBundle:Tag',
        'query_builder' => function(TagRepository $tr) use ($someCustomParam) 
        {
            return $tr->findObjectNotMine($someCustomParam);
        }
    );

    // ....
}

Очевидным недостатком этого является необходимость для всех форм в пути иметь setRequired или setDefault.

Надеюсь, это поможет ...

...