更新表单集合中的单个实体

时间:2017-03-31 16:01:49

标签: symfony symfony-forms symfony-3.1

我有一个页面,我可以在其中添加/更新数据库中的某些实体。对于更新,我有一个表格,我可以从一些表格中获得每一行的列表。我需要有可能编辑这一行(实体)并保存/删除。这意味着表的每一行必须具有来自数据库的一个对象的表单字段。我想有可能验证这种形式。所以我在一个页面中有很多相同类型的表格 上一篇文章我刚创建了一个循环,我以这种方式保存在具有相同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代码来查找此表单中最接近的表单和序列化字段,然后数据将转到控制器。

enter image description here

0 个答案:

没有答案