2016-07-15 81 views
1

我沒有什麼問題用symfony創建collectiontype ..返回爲空Symfony3 CollectionType,數據

我試圖跟隨多個教程,像 http://symfony.com/doc/current/cookbook/form/form_collections.htmlhttp://toni.uebernickel.info/2012/03/15/an-example-of-symfony2-collectiontype-form-field-prototype.html ..

但總是相同的結果。

$tags = $form->get('tags')->getData();返回null。

我能夠生成添加/刪除鏈接和索引工作藏漢,但將數據傳輸到控制器...

我失去了一些重要的或做錯了什麼?希望有人能幫助我或給小費。

我目前有

任務實體

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

任務類型

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

編輯/ UPDATE

任務實體getter和setter方法的標籤

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

已更新的問題,getters和setter是使用php bin/console doctrine生成的:generate:entities - 命令 – Degu

回答

1

感謝您更新您的問題,並提供更多詳細信息。

要立即解決您的問題,請記住,Doctrine級聯只會檢查擁有方(具有inversedBy的一方 - 在此情況下需要保留它的位置)。所以你應該手動設置一個標籤應該有的任務。

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

假設 - 我相信,你有沒有檢查你的實際需要。爲了正確的解決方案,我假設你需要這個功能,一個任務有多個標籤,一個標籤可以在多個任務中重複使用。

在這種情況下:

1.您使用的是一對多的關係。如果你看一下你提到的第一個教程,需要多對多http://symfony.com/doc/current/cookbook/form/form_collections.html

2.此外,你需要一個單向多對多。爲什麼?您正在任務內分配標籤,而不是相反。另外,也許你需要標記其他實體。

有關多對多(單向)文檔看看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; 

標籤實體

保護$任務;


注意:當您從任務中刪除標籤,並沒有其他的任務是使用你刪除一個標籤,標籤將被保留爲「孤兒」。在ManyToMany關係中,Doctrine不能很好地處理孤兒刪除問題,因此您必須手動刪除這些孤兒。或者,您可以將標籤放置在未使用的位置,稍後再添加。

+0

最後!無眠一週後,設法找到解決方案..仍不知道爲什麼,但ajax調用提交按鈕打破了collectiontype..somehow ..我接受這個答案,事件並沒有解決我的問題,但很好地解釋和改進。 :) – Degu