2016-07-15 2 views
1

У меня есть небольшая проблема, создавая collectiontype с Symfony ..Symfony3 CollectionType, данные возвращает утратившим

Я пытался следовать несколько учебник, как http://symfony.com/doc/current/cookbook/form/form_collections.html или http://toni.uebernickel.info/2012/03/15/an-example-of-symfony2-collectiontype-form-field-prototype.html ..

, но всегда с тем же результатом.

$tags = $form->get('tags')->getData(); возвращение не применяется.

Я способен генерировать добавить/удалить ссылку и индексирование работает как хорошо, но получение данных в контроллер ...

Я пропускаю что-то важное или делать что-то не так? Надеюсь, кто-то может помочь мне или дать отзыв.

то, что я в настоящее время

сущности Задача

/** 
* @ORM\OneToMany(targetEntity="Tag", mappedBy="task", 
cascade={"persist", "remove"}) 
*/protected $tags; 

Тэг лица

/** 
* @ORM\ManyToOne(targetEntity="Task", inversedBy="tags") 
* @ORM\JoinColumn(name="tag_id", referencedColumnName="id") 
*/
protected $task; 

TaskType

->add('tags', CollectionType::class, array(
'entry_type' => TagType::class, 
'allow_add' => true, 
'allow_delete' => true, 
'prototype_name' => '__tag__name__',)) 

TagType

$builder->add('name', TextType::class, array())); 

Макро

{% macro widget_prototype(widget, remove_text) %} 
    {% if widget.vars.prototype is defined %} 
     {% set form = widget.vars.prototype %} 
     {% set name = widget.vars.prototype.vars.name %} 
    {% else %} 
     {% set form = widget %} 
     {% set name = widget.vars.full_name %} 
    {% endif %} 

    <div data-content="{{ name }}"> 
     <a class="btn-remove" data-related="{{ name }}">{{ remove_text }}</a> 
     {{ form_widget(form) }} 
    </div> 

{% endmacro %} 

Туиг

<div id="post_tags" data-prototype="{{ _self.widget_prototype(form.tags, 'Remove tag')|escape }}"> 
{% for widget in form.tags.children %} 
    {{ _self.widget_prototype(widget, 'Remove tag') }} 
{% endfor %} 
</div> 
<a class="btn-add" data-target="post_tags">Add tag</a> 

JS

jQuery(function($) { 
    $(document).on('click', '.btn-add[data-target]', function(event) { 
     var collectionHolder = $('#' + $(this).attr('data-target')); 

     if (!collectionHolder.attr('data-counter')) { 
      collectionHolder.attr('data-counter', collectionHolder.children().length); 
     } 

     var prototype = collectionHolder.attr('data-prototype'); 
     var form = prototype.replace(/__tag__name__/g, collectionHolder.attr('data-counter')); 

     collectionHolder.attr('data-counter', Number(collectionHolder.attr('data-counter')) + 1); 
     collectionHolder.append(form); 

     event && event.preventDefault(); 
    }); 

    $(document).on('click', '.btn-remove[data-related]', function(event) { 
     var name = $(this).attr('data-related'); 
     $('*[data-content="'+name+'"]').remove(); 

     event && event.preventDefault(); 
    }); 
}); 

и контроллер

$form = $this->createForm(TaskType::class, $task); 

EDIT/UPDATE

Task Entity сеттеров и добытчиками для тегов

public function __construct() 
{ 
    $this->tags = new \Doctrine\Common\Collections\ArrayCollection(); 
} 

public function add(Tag $tag) 
{ 
    $this->tags[] = $tag; 
    return $this; 
} 

public function removeTag(Tag $tag) 
{ 
    $this->tags->removeElement($tag); 
} 

public function getTags() 
{ 
    return $this->tags; 
} 

контроллера:

$task = new Task(); 
$form = $this->createForm(TaskType::class, $task); 
$form->handleRequest($request); 
if($form->isValid()){ 
    $tags = $form->get('tags')->getData(); 

    foreach($tags as $tag){ 
     //Here var_dump, echo, print, array_push etc tricks = empty 
    } 

    //Also without foreach var_dump = empty 
} 
+0

Показать ваши геттеры и сеттеры (для тегов) в объекте задачи, пожалуйста. – galeaspablo

+0

вы могли бы разместить весь контроллер или, по крайней мере, соответствующие части, где вы пытаетесь получить данные тэгов? – DonCallisto

+0

обновленный вопрос, геттеры и сеттеры генерируются с помощью php bin/console doctrine: generate: entities - command – Degu

ответ

1

Благодарим за обновление вашего вопроса более подробно.

Чтобы решить вашу проблему сразу, помните, что каскад Doctrine проверяет только принадлежащую стороне (сторона, у которой есть обратная сторона - которая в этом случае должна оставаться там, где она есть). Поэтому вы должны вручную установить задачу, которую должен иметь тег.

public function add(Tag $tag) 
{ 
    $this->tags[] = $tag; 
    $tag->task = $this;//added this line 
    return $this; 
} 

Успенская - Я считаю, что вы не изучили то, что вам действительно нужно. Для правильного решения я предполагаю, что вам нужна эта функциональность, одна задача имеет несколько тегов, а тег можно повторно использовать для нескольких задач.

В этом случае:

1. Вы используете отношения OneToMany. Если посмотреть на первом уроке вы ссылаетесь, вам нужно ManyToMany (http://symfony.com/doc/current/cookbook/form/form_collections.html)

2. Кроме того, вам нужно однонаправленный ManyToMany. Почему? Вы назначаете теги внутри задачи, а не наоборот. Кроме того, возможно, вам нужно будет пометить другие объекты.

Для документации на ManyToMany (однонаправленного) посмотреть на http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-unidirectional


целевой сущности

/** 
* @var ArrayCollection 
* 
* @Assert\Valid 
* @ORM\ManyToMany(targetEntity="Tag") 
* @ORM\JoinTable(name="tasks_tags", 
* joinColumns={@ORM\JoinColumn(name="task_id", referencedColumnName="id", onDelete="CASCADE")}, 
* inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")} 
*) 
*/ 
protected $tasks; 

Tag объектные

защищенных $ задач;


Примечания: При удалении тегов из задачи, и никаких других задач не с помощью тега вы удален, тег будет оставлен как «сирота». Doctrine не работает с удалением сирот в отношениях ManyToMany, поэтому вам придется удалить этих сирот вручную. Или вы можете оставить тег, лежащий вокруг, неиспользуемый, который будет добавлен позднее.

+0

Наконец-то! После бессонной недели удалось найти решение. Все еще не знаю, почему, но ajax-вызов, связанный с кнопкой отправки, нарушил набор экземпляров .. как-то .. Я принимаю это как ответ, eventhought не решает мою проблему, но хорошо объясняется и улучшается. :) – Degu

Смежные вопросы