Теги, использующие select2 и symfony/doctrine

Я пытаюсь использовать плагин Select2 jQuery с компонентом формы Symfony и Doctrine, чтобы создать поле тега, куда я могу добавлять существующие теги и создавать новые на лету.

Все идет нормально. Я использую следующий код инициализации Select2:

$('select.tags').select2({
    tags: "true"
});

Все существующие теги загружаются при каждом запросе. Новые должны быть созданы/сохранены при отправке всей формы. (Так что никакой магии AJAX.)

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

Это должно произойти где-то между:

if ($form->isSubmitted()) {
}

и

if ($form->isValid()) {
}

в моем контроллере. Но я не могу представить, как лучше всего это сделать (или есть ли вообще).

Я читал о сборе форм, но почему-то это не совсем то, что мне нужно. Потому что там у вас есть одно единственное поле input для каждого тега. Но у меня есть поле select с динамически добавленными новыми параметрами.


person TiMESPLiNTER    schedule 04.12.2015    source источник
comment
Вы смотрели на symfony.com/doc/current/components/form/ form_events.html ?   -  person Jay    schedule 04.12.2015
comment
@Jay Спасибо за подсказку. Думаю, тогда мне нужно событие FormEvents::PRE_SUBMIT ... поэтому я создал EventSubscriber и зарегистрировал его через services.yml. Вызывается метод getSubscribedEvents(). Но метод, зарегистрированный для события, не регистрируется. Работает ли регистрация подписчиков событий для FormEvents поверх services.yml?   -  person TiMESPLiNTER    schedule 04.12.2015


Ответы (2)


как только я сделал то же самое, я отделил логику от конструктора форм, сейчас у меня нет кода, но в псевдо:

убедитесь, что выбранные вами теги записаны в текстовый ввод в виде строки с некоторым разделителем, sth. нравится

<input name="tags" value="tag1|tag2|tag3|" ..>

в контроллере вы проверяете, отправлена ​​​​ли форма и действительна

тогда у вас есть ваша сущность

$entity=$form->getData()

и теги

$tags = explode("|",$request->get('tags'));

затем вы перебираете их и добавляете в свою сущность, если тег еще не существует, вы его создаете

foreach($tags as $tag){
   $tag = $tagrepo->findOneByName($tag)
   if(!$tag){
     $newTag = new Tag();
     $newTag->setName($tag);
     $em->persist($newTag);
     $entity->addTag($newTag);
   }else{
     $entity->addTag($tag);
   }
  $em->flush();

}
person john Smith    schedule 04.12.2015

Новые должны быть созданы/сохранены при отправке всей формы.

Итак, почему вы не хотите сохранять их после этой строки:

if ($form->isValid()) {
}

РЕДАКТИРОВАТЬ

Однажды я создал преобразователь для тегов. Он изменяет набор тегов на один, разделенный запятыми. После отправки преобразователь возвращает текст в коллекцию Теги.

/**
 * Class TagTransformer
 * @package AppBundle\Form\Transformer
 *
 * @DI\Service("app.form.transformer.tag")
 */
class TagTransformer implements DataTransformerInterface{

    /**
     * @var EntityManager
     */
    private $em;

    /**
     * @param EntityManager $em
     * @DI\InjectParams(params={
     *      "em" = @DI\Inject("doctrine.orm.entity_manager")
     * })
     */
    public function __construct($em)
    {
        $this->em = $em;
    }

    /**
     * @param ArrayCollection | Tag[] $value
     * @return string
     */
    public function transform($value)
    {
        if($value == null) $value = array();

        $string = "";
        foreach($value as $tag)
            $string .= $tag->getName().",";
        return $string;
    }


    /**
     * @param string $value
     * @return ArrayCollection
     */
    public function reverseTransform($value)
    {
        $collection = new ArrayCollection();

        if(strlen($value) == 0) return $collection;

        $names = explode(",",$value);
        foreach($names as $name){
            $tag = $this->em->getRepository('AppBundle:Def\Tag')->findOneByName($name);
            if(!$tag) $tag = new Tag();

            $tag->setName($name);
            $collection->add($tag);
        }

        return $collection;
    }
}
person Koovvall    schedule 04.12.2015
comment
Потому что есть недопустимые варианты. Доступные варианты — все существующие теги. Но новый тег не существует и поэтому недействителен. - person TiMESPLiNTER; 04.12.2015