我遇到的問題是關於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文檔,並創建了這些嵌入式表單,但文檔只聲明我正在嘗試做的事情是可能的,沒有示例。我不知道如果我正在做的是處理這種嵌入式表單的正確方法,或者我在這個過程中丟失了一些步驟。
有關這個問題的任何信息或幫助是非常值得歡迎的!