2017-07-25 73 views
1

我遇到的問題是關於Symfony的(3)formbuilder。我有3個實體爲其創建了3個FormTypes。見下文;代碼下面的實際問題。使用Symfony的Formbuilder保存多個嵌入表單,多個主節點工作正常,深度達到2級。 (1對多),

我有以下實體:

DocumentBaldoc 1 - > * DocumentBaldocConnectionPoint 1 - > * DocumentBaldocAccount

我儘量做到以下幾點。我想爲DocumentBaldoc創建一個表單,我想爲DocumentBaldocConnectionPoints創建多個表單,並且我想爲DocumentBaldocConnectionPointAccounts創建多個表單。保存時,這些需要使用關係(fk)存儲在數據庫中。

我有DocumentBaldoc下面的類(表)

namespace FooBundle\Form\Documents\Baldoc; 

use FooBundle\Entity\Documents\Baldoc\DocumentBaldoc; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\Extension\Core\Type\SubmitType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 
use Symfony\Component\Form\Extension\Core\Type\CollectionType; 

class DocumentBaldocType extends AbstractType 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('document_release') 
      ->add('identification') 
      ->add('version') 
      ->add('type') 
      ->add('creationDateTime') 
      ->add('validityPeriod') 
      ->add('contractReference') 
      ->add('contractType') 
      ->add('issuerMarketParticipantIdentification') 
      ->add('issuerMarketParticipantIdentificationCodingScheme') 
      ->add('issuerMarketParticipantMarketRoleCode') 
      ->add('recipientMarketParticipantIdentification') 
      ->add('recipientMarketParticipantIdentificationCodingScheme') 
      ->add('recipientMarketParticipantMarketRoleCode') 
      ->add('applicationContext') 
      ->add('applicationContextCodingScheme') 
      ->add('connectionPoints', CollectionType::class, [ 
       'entry_type' => DocumentBaldocConnectionPointType::class, 
       'allow_add' => true, 
       'by_reference' => false, 
      ]) 
      ->add('save', SubmitType::class); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => DocumentBaldoc::class 
     )); 
    } 
} 

我有以下類DocumentBaldocConnectionPoint(表格)

namespace FooBundle\Form\Documents\Baldoc; 

use FooBundle\Entity\Documents\Baldoc\DocumentBaldocConnectionPoint; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\Extension\Core\Type\CollectionType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

class DocumentBaldocConnectionPointType extends AbstractType 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('identification') 
      ->add('identificationCodingScheme') 
      ->add('measureUnitCode') 
      ->add('accounts', CollectionType::class, [ 
       'entry_type' => DocumentBaldocAccountType::class, 
       'allow_add' => true, 
       'by_reference' => false, 
      ]); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => DocumentBaldocConnectionPoint::class 
     )); 
    } 
} 

和我有DocumentBaldocAccount(表格)下面的類

namespace FooBundle\Form\Documents\Baldoc; 

use FooBundle\Entity\Documents\Baldoc\DocumentBaldocAccount; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

class DocumentBaldocAccountType extends AbstractType 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('identification') 
      ->add('identificationCodingScheme') 
      ->add('accountTso') 
      ->add('accountTsoCodingScheme'); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => DocumentBaldocAccount::class 
     )); 
    } 

} 

我使用Symfony的formbuilder來生成DocumentBaldoc實體的表單。通過添加一個帶有DocumentBaldocConnectionPoint的CollectionType作爲entry_type,我可以在模板中使用原型變量。

{% block DOCUMENT %} 
    {{ form_start(form) }} 
    <ul class="connectionPoints" 
     data-prototype="{{ form_widget(form.connectionPoints.vars.prototype)|e('html_attr') }}"> 
     {{ form_widget(form) }} 
    </ul> 
    {{ form_end(form) }} 
{% endblock %} 

在此之後,我可以使用JavaScript來創建DocumentBaldocConnectionPoint形式層出不窮,當我按下了FK拯救那些(多!)DocumentBaldocConnectionPoints存儲在DB父DocumentBaldoc。

到目前爲止,這工作得非常好,但問題出現在我想爲DocumentBaldocConnectionPointAccount執行相同操作時出現。 DocumentBaldocConnectionPoint表單在頁面加載時不存在,所以我無法直接訪問原型屬性,我通過創建一些在創建DocumentBaldocConenctionPoint表單時觸發的Javascript邏輯來解決此問題。然後遵循與其父母相同的邏輯。我遇到的問題是我無法保存多個DocumentBaldocConenctionPointAccounts,它總是保存最後一個,這讓我認爲在進程中的某個地方它不會保存爲數組,或者數組被最後一個條目覆蓋。我一直在修補它幾天,但無法找到任何邏輯差異(formtypes或實體,關係定義遵循相同的結構),這使我認爲我沒有使用它,因爲它應該被使用。

這些是兩個實體的Annotation關係定義,$ connectionPoints和$ accounts都在實體的構造函數中實例化爲ArrayCollections。

// DocumentBalcon 
@ORM\OneToMany(targetEntity="DocumentBaldocConnectionPoint", mappedBy="document", cascade={"persist"}) 
private $connectionPoints; 

// DocumentBalconConnectionPoint 
@ORM\OneToMany(targetEntity="DocumentBaldocAccount", mappedBy="connectionPoint", cascade={"persist"}) 
private $accounts; 

脫穎而出的唯一的事情是,DocumentBaldocConnectionPoint形式的雛形呈現與需要與一個唯一的標識符來代替,當我搶DocumentBaldocConnectionPointAccount原型同樣的事情不會發生的__name__語法,我通過創建自己的標識符來解決這個問題,以保證唯一性。

我讀過他關於formbuilder的Symfony文檔,並創建了這些嵌入式表單,但文檔只聲明我正在嘗試做的事情是可能的,沒有示例。我不知道如果我正在做的是處理這種嵌入式表單的正確方法,或者我在這個過程中丟失了一些步驟。

有關這個問題的任何信息或幫助是非常值得歡迎的!

回答

0

問題解決。

第一個子表單DocumentBaldocConnectionPoint還包含屬性原型,其中包含DocumentBaldocConnectionPointAccount的表單。當更改DocumentBaldocConnectionPoint中的__name__值時,DocumentBaldocConnectionPointAccount als的值無意中發生了更改,導致意外的行爲,即每個DocumentBaldocConnectionPointAccount表單被置於值爲'index'的鍵上的數組中,該值只能根據DocumentConnectionPoint更改。

我使用的溶液如下:

在功能buildForm我添加有值「賬戶」原型鍵這使我抓取按名稱參考原型形式的可能性DocumentBaldocConnectionPointType類

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('identification') 
     ->add('identificationCodingScheme') 
     ->add('measureUnitCode') 
     ->add('accounts', CollectionType::class, [ 
      'entry_type' => DocumentBaldocAccountType::class, 
      'allow_add' => true, 
      'by_reference' => false, 
      'prototype' => 'accounts' 
     ]); 
} 

在樹枝模板我添加一個div如下:

<div id="prototypes" 
    data-prototype-account="{{ form_widget(form.connectionPoints.vars.prototype.children['accounts'].vars.prototype) | e }}" 
    data-prototype-connection-point="{{ form_widget(form.connectionPoints.vars.prototype) | e }}"> 
</div> 

這導致在原型形式被存儲在一個DIV,給我的可能性,方便地查詢並在需要時使用它們。