@更新如下
我读过https://symfony.com/doc/current/form/form_collections.html,它可以在这个文档中的一个例子中顺利工作。现在我想反向操作(零件->票证-用票证数据渲染零件)
我希望能够更新多个表单的数据,然后用一个按钮提交它。在这种情况下,每个部分都是单独的表单。现在我所实现的是将多个formView()放入一个数组中,然后呈现它-它具有来自数据库的数据,但这些是不同的表单:(.
主要的问题是,当我创建新的表单PartColletionType并向那里传递多个part对象时,它不会在页面上呈现它,但我可以添加新的PartsType表单。我假设问题要么与关系(ManyToOne -每个part只能有一个ticket)有关,要么与PartCollectionType的'data_class'有关。
Ticket.php
#[ORM\OneToMany(mappedBy: 'ticket', targetEntity: Part::class , cascade: ['persist'])]
private Collection $parts;
Part.php
#[ORM\ManyToOne(inversedBy: 'parts')]
private ?Ticket $ticket = null;
据我所知,这是一个包含其他形式的形式,所以我应该能够提交与按钮“UpdateAllParts”和学说的每一个孩子的形式将做其余的工作
class PartColletionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('UpdateAllParts' , SubmitType::class , [])
->add('partsType' , CollectionType::class , [
'entry_type' => PartsType::class,
'allow_add' => true,
'mapped' => false,
'allow_delete' => true
]);;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
//I dont know if I have to set there data_class if yes which type?
// 'data_class' => null,
// 'data_class' => PartsType::class,
]);
}
}
class PartsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('submit' , SubmitType::class , [])
->add('partNumber' , TextType::class , [])
->add('distribution' , TextType::class , [])
->add('upsTrack' , TextType::class , [])
->add('returnalbe' , TextType::class , [])
->add('sendDate' , DateType::class , [])
->add('SOID' , TextType::class , [])
//It's a form to display additional Part's Ticket data
->add('ticket' , TicketPartType::class , [
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Part::class,
]);
}
}
部件附加:
class TicketPartType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('Institution')
->add('productName')
->add('productSerialNumber')
->add('externalTicketID')
->add('realisationTechnican' , EntityType::class , [
'mapped' => true,
'class' => Technican::class,
'choice_label' => function (Technican $t): string {
return $t->getTechnicanSurname() . ' ' . $t->getCity();
}]);
}
在控制器中,我传递多个票证
$parts = $doctrine->getRepository(Part::class)->findAll();
$parts = $formFactory->createNamed('ticketsparts' , PartColletionType::class , $parts);
return $this->renderForm('mba/ticketparts.html.twig' , ['parts' => $parts ]);
这是我的小树枝模板
{% macro printPartForm(partsType , productSerialNumber) %}
{{form(partsType)}}
{% endmacro %}
{% import _self as formMacros %}
<div class="parts0 row g-0" style="background:#CCC;"
data-index="{{ parts.partsType|length > 0 ? p.parts|last.vars.name + 1 : 0 }}"
data-prototype='{{ formMacros.printPartForm(parts.partsType.vars.prototype)|e('html_attr') }}'>
{% for part in parts.partsType %}
<div class="row part" >
{{ formMacros.printPartForm(part)}}
</div>
{% endfor %}
</div>
update所以现在我设置PartColletionType数据类为:
'data_class' => PartRepository::class
然后将Part repository传递到表单
$parts = $formFactory->createNamed('ticketsparts' , PartColletionType::class , $doctrine->getRepository(Part::class));
现在,在twig中,我可以通过调用传递给TWIG('parts')的参数的方法来访问所需的实体,并且所有内容都正确呈现。
{% form_theme parts 'bootstrap_5_layout.html.twig' %}
{{form_start(parts, {'attr': {'class':''}}) }}
{{form_row(parts.field_name)}}
{% for item in parts.findByExampleField %}
<div class="row bg-warning m-5 ">
<div class="div col-1 ps-2 pe-2 bg-warning">{{form_row(item.ticket.id)}}</div>
<div class="div col-2 ps-2 pe-2 bg-warning">{{form_row(item.ticket.externalTicketID)}}</div>
<div class="div col-1 ps-2 pe-2 bg-warning">{{form_row(item.returnalbe)}}</div>
<div class="div col-1 ps-2 pe-2 bg-warning">{{form_row(item.sendDate)}}</div>
<div class="div col-1 ps-2 pe-2 bg-warning">{{form_row(item.SOID)}}</div>
</div>
{% endfor %}
{{form_end(parts)}}
现在的问题是如何处理好它?
@Edit2ok.
if(isset($_POST['ticketsparts'])){
$parts->handleRequest($request);
if($parts->isSubmitted() && $parts->isValid()){
var_dump('submitted and valid');
$submittedParts= $parts->get('findByExampleField')->getData();
foreach($submittedParts as $c){
$doctrine->getManager()->persist($c);
}
$doctrine->getManager()->flush();
}
}
是不是很混乱?考虑到我们将repository传递给twig,它对性能有多大影响?在我的情况下,“selectByExampleField”将被限制在~100个实体,所以可能不会有问题,但每次编辑单个对象都会发送整个数据。
感谢您的帮助
1条答案
按热度按时间brvekthn1#
所以...上面的分辨率是...不好的。你不能控制你想要显示的内容。所以让我们说-对于每一个排序方向,你必须制作单独的表单。
也许有人会发现这很有用。我在下面做了一些修改,其余的代码和上面的一样。
它确实呈现多个表单-单个部分与相关的门票数据,只需单击一下,我就可以提交多个部分。
//Controller.php
//PartColletionType.php