我有一个页面,我可以在其中添加/更新数据库中的某些实体。对于更新,我有一个表格,我可以从一些表格中获得每一行的列表。我需要有可能编辑这一行(实体)并保存/删除。这意味着表的每一行必须具有来自数据库的一个对象的表单字段。我想有可能验证这种形式。所以我在一个页面中有很多相同类型的表格 上一篇文章我刚创建了一个循环,我以这种方式保存在具有相同formtype的表单数组中:
$formsArray = [];
foreach ($gardens as $garden) {
array_push($formsArray, $this->createForm('AppBundle\Form\GardenType', $garden)->createView());
}
然后我在模板(树枝)中展示了它:
{% for key, form in forms %}
<tr {% if key is not divisible by (2) %} class="gray" {% endif %}>
{{ form_start(form, { 'attr': {'name' : 'garden ', 'action': path('ajax_garden_update', {id : form.vars.value.id}), 'role' : 'form', 'class' : 'ajaxUpdate'} }) }}
<td class="form-group">{{ form_widget(form.name) }}</td>
<td class="form-group">{{ form_widget(form.rows) }}</td>
<td class="form-group">
<span id="form-status"><button type="submit" class="btn btn-default btn-icon btn-save"><i class="icon-disk"></i></button></span>
</td>
{{ form_end(form) }}
</tr>
{% endfor %}
在表的每一行中我都有提交按钮,所以我可以序列化表单,将其发送到服务器,以及我如何更新实体:
public function ajaxUpdateAction(Request $request, Garden $garden)
{
if ($request->isXMLHttpRequest()) {
$form = $this->createForm(GardenType::class, $garden);
$form->handleRequest($request);
if ($form->isValid()) {
$gardenManager = $this->get('app.manager.garden');
$gardenManager->updateGarden($garden);
return new JsonResponse(['code' => 202, 'status' => 'success'], 202);
} else {
$serializer = $this->get('jms_serializer');
return new JsonResponse($serializer->serialize(['error' => $form], 'json'), 500);
}
}
return new Response('Request not valid', 400);
}
但我有一种感觉,即在循环中为表单创建一个数组,这对于内存和速度来说是一个坏主意。所以我尝试使用表单集合。但问题是我不明白如何从集合中验证和更新单个实体。当我尝试处理请求并验证集合时,我收到错误。 首先,我得到的错误形式没有csrf令牌(表单只能有一个令牌,所以我发送没有令牌的表单,也许我需要找到一种方法为每一行生成令牌)。然后我禁用了csrf保护并得到错误,表单不能有额外的字段。也许我做错了什么?这是我的收藏。
<?php
namespace AppBundle\Form\Collection;
use AppBundle\Entity\Garden;
use AppBundle\Form\GardenType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class GardensType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('garden', CollectionType::class, [
'entry_type' => GardenType::class,
'allow_add' => true,
'prototype' => true,
'csrf_protection' => false
]);
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'csrf_protection' => false,
'validation_groups' => false,
'allow_extra_fields' => true
));
}
}
我在控制器中的代码:
/**
* @param Request $request
* @param Garden $garden
* @return JsonResponse|Response
*/
public function ajaxUpdateAction(Request $request, Garden $garden)
{
if ($request->isXMLHttpRequest()) {
$form = $this->createForm(GardensType::class);
$form->handleRequest($request);
if ($form->isValid()) {
$gardenManager = $this->get('app.manager.garden');
$gardenManager->updateGarden($garden);
return new JsonResponse(['code' => 202, 'status' => 'success'], 202);
} else {
$serializer = $this->get('jms_serializer');
return new JsonResponse($serializer->serialize(['error' => $form], 'json'), 500);
}
}
return new Response('Request not valid', 400);
}
P.S。我附上图片以便更好地理解。它从集合中形成的每一行和行中的每个按钮都使用js代码来查找此表单中最接近的表单和序列化字段,然后数据将转到控制器。