2016-07-15 10 views
1

ich wenig Probleme haben Collection zu schaffen mit symfony ..Symfony3 Collection, gibt Daten als null

ich versucht habe mehrere Tutorial zu folgen, wie http://symfony.com/doc/current/cookbook/form/form_collections.html oder http://toni.uebernickel.info/2012/03/15/an-example-of-symfony2-collectiontype-form-field-prototype.html ..

aber immer mit demselben Ergebnis.

$tags = $form->get('tags')->getData(); gibt null zurück.

ich in der Lage bin add zu erzeugen/entfernen Link und Indizierung arbeitet als gut, aber die Daten in die Steuerung immer ...

Fehle ich etwas Wichtiges oder etwas falsch zu machen? Hoffe jemand kann mir helfen oder Trinkgeld geben.

, was ich habe zur Zeit

Task-Einheit

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

Tag Entität

/** 
* @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

{% 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 %} 

Zweig

<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(); 
    }); 
}); 

und in -Controller

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

EDIT/UPDATE

Task-Entity Getter und Setter für Tags

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; 
} 

Controller:

$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

Zeigen Sie Ihre Getter und Setter (für Tags) in der Entität Task bitte. – galeaspablo

+0

könnten Sie den gesamten Controller oder zumindest die relevanten Teile veröffentlichen, in denen Sie versuchen, Tag-Daten zu erhalten? – DonCallisto

+0

aktualisierte Frage, Getter und Setter werden mit PHP bin/console doctrine erzeugt: generate: entities - command – Degu

Antwort

1

Vielen Dank für die Aktualisierung Ihrer Frage mit mehr Details.

Um Ihr Problem sofort zu lösen, denken Sie daran, dass Doctrine Cascade nur die Besitzerseite (die Seite, die invertedBy hat - die in diesem Fall bleiben muss, wo es ist) überprüft. Sie sollten also die Aufgabe manuell festlegen, die ein Tag haben soll.

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

Annahme - Ich glaube, dass Sie nicht untersucht haben, was Sie wirklich brauchen. Für die richtige Lösung nehme ich an, Sie benötigen diese Funktionalität, eine Aufgabe hat mehrere Tags und ein Tag kann für mehrere Aufgaben wiederverwendet werden.

In diesem Fall:

1. Sie sind eine OneToMany Beziehung verwenden. Wenn Sie beim ersten Tutorial schauen Sie sich beziehen, müssen Sie ManyToMany (http://symfony.com/doc/current/cookbook/form/form_collections.html)

2. Darüber hinaus müssen Sie eine unidirektionale ManyToMany. Warum? Sie weisen Tags innerhalb einer Aufgabe zu, nicht umgekehrt. Außerdem müssen Sie möglicherweise andere Entitäten markieren.

Zur Dokumentation auf ManyToMany (unidirektional) haben einen Blick auf http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-unidirectional


Task-Einheit

/** 
* @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 Entität

geschützt $ Aufgaben;


Hinweis: Wenn Sie Tags aus einer Aufgabe löschen, und keine andere Aufgaben einen Tag, das Sie gelöscht verwenden, wird der Tag als „Waise“ gelassen werden. Doctrine funktioniert nicht gut mit dem Entfernen von verwaisten Objekten in ManyToMany-Beziehungen. Sie müssen diese Waisen also manuell entfernen. Oder Sie können das Etikett herumliegen lassen, unbenutzt, um es zu einem späteren Zeitpunkt hinzuzufügen.

+0

Endlich! Nach der schlaflosen Woche geschafft, Lösung zu finden .. Immer noch nicht wissen, warum, aber Ajax Anruf mit Absenden Button brach Sammlertyp .. etwas .. Ich akzeptiere dies als Antwort, eventhought hat nicht mein Problem gelöst, ist aber gut erklärt und Verbesserung. :) – Degu