Symfony 3 - Определить форму как услугу

в моем проекте Symfony 3-master я использую этот код для создания формы в контроллере:

$form = $this->createForm(ApplicantType::class, $applicant);

Теперь я решил сделать сервис из этой формы, поэтому я могу использовать EntityManager внутри него. Так что в Symfony2.x это было бы довольно просто, просто с объявлением в services.yml и этой строке кода:

$form = $this->createForm($this->get("applicant.form"), $applicant);

Однако это уже невозможно в Symfony 3, потому что этот первый параметр ожидает строку, а не сама форма.

Поэтому мой вопрос: как мне создать форму в качестве службы в Symfony 3, или есть ли другой способ передачи EntityManager внутри формы?

Спасибо за любую помощь!

Ответы

Ответ 1

Определение типа формы как службы не означает передачу экземпляра, извлеченного из контейнера, в createForm. при этом контейнер не участвует в том, что касается компонента формы.

Чтобы использовать тип формы, зарегистрированный как услугу (с тегом form.type чтобы компонент формы знал об этом), вы просто просто ссылаетесь на него по его имени (то есть полное имя класса в Symfony 2. 8+ и имя типа в более старых версиях) в createForm или в FormBuilder::add. Это именно то, что вы делаете для основных типов Symfony btw (text, choice и т.д.), Которые регистрируются как службы. код вашего контроллера вообще не изменяется при использовании типа формы как службы, а не имеет тип формы без зависимости и неявно регистрируется при первом использовании.

Ответ 2

Это то, что я сделал, чтобы ввести форму в качестве службы в Symfony 3 из моего кода Symfony 2.

В моем service.yml я изменил

issue.form:
    class: Gutersohn\Bundle\CoreBundle\Form\IssueType
    arguments: ['@service_container']
    tags:
        - { name: form.type, alias: issue }

в

issue.form:
    class: Gutersohn\Bundle\CoreBundle\Form\IssueType
    arguments: ['@service_container']
    tags:
        - { name: form.type }

В моем контроллере я изменил

$form = $this->container->get('form.factory')->create($this->container->get('issue.form'), $issue, [
        "method" => "post",
        "action" => $this->container->get('router')->generate("ticket_add")
]);

в

$form = $this->container->get('form.factory')->create(IssueType::class, $issue, [
        "method" => "post",
        "action" => $this->container->get('router')->generate("ticket_add")
]); 

Ответ 3

В выпуске № 17013 на GitHub aliemre заявил:

Добавление тега form.type достаточно в определении вашего сервиса.

app.form.corporation_type:
    class: App\CorporationBundle\Form\CorporationType
    arguments: ["@doctrine.orm.entity_manager"]
    tags:
        - { name: form.type }

Контроллер должен оставаться таким же:

$form = $this->createForm(CorporationType::class, $corporation);

Я тестировал и работает!

Ответ 4

Я попытался изучить проблему, и я вникаю в изменение в github, которое является следующим: https://github.com/symfony/symfony/commit/abca2d6fdc89479586e052cd11241d5a9bc885e5#diff-5c1348d69be32426ff20446c9e812365R64

Затем я нашел PR в Symfony, у которого есть это удаление BC, я решил спросить, почему причина, и вы можете увидеть это здесь: https://github.com/symfony/symfony/pull/16075#issuecomment-165106123

Надеюсь, это поможет вам с концепцией вокруг нее!