jquery - Symfony2 : Add Collection via AJAX Outside of Symfony

标签 jquery ajax symfony symfony-forms symfony-2.7

我正在尝试通过 REST API 传递表单数据。 API 是在 Symfony (2.7) 中构建的,实际的数据输入表单位于外部非 symfony 站点上。表单提交得很好,直到我尝试传递一对“集合”。

我一直在关注this tutorial因此我的 Type 类中有以下内容:

$form->add('event', 'collection', array(
    'type' => new AvRequestEventType(),
    'allow_add' => true,
    'by_reference' => false,
));

$form->add('equipment', 'collection', array(
    'type' => new AvRequestEquipmentQuantityType(),
    'allow_add' => true,
    'by_reference' => false,
)); 

我的数据输入表单如下所示(我将仅显示“事件”集合,因为“设备”集合代码本质上是相同的):

      var eventsPrototype = '<div id="event___name__" class="row"><div class="small-8 columns"><label for="event___name___location">Location<input type="text" id="event___name___location" name="[event][__name__][location]" maxlength="100" /></label></div><div class="small-4 columns"><label for="event___name___time">Time<input type="time" id="event___name___time" name="[event][__name__][time]" /></label></div></div>';
      var $eventsHolder;
      var $addEventLink = $('<a href="#" class="add_event_link">Add Event</a>');
      var $newLinkLi = $('<li></li>').append($addEventLink);

      $eventsHolder = $('ul.events');
      $eventsHolder.append($newLinkLi);

      /*
        count the current form inputs we have (e.g. 2), use that as the new
        index when inserting a new item (e.g. 2)
      */
      $eventsHolder.data('index', $eventsHolder.find(':input').length);

      //add a new event form on page load
      addEventForm($eventsHolder, $newLinkLi);

      $addEventLink.on('click', function(event){
      event.preventDefault();

      //add a new event form
        addEventForm($eventsHolder, $newLinkLi);
      });

      function addEventForm($eventsHolder, $newLinkLi) {
        // get the new index
        var index = $eventsHolder.data('index');

        // Replace '__name__' in the prototype's HTML to
        // instead be a number based on how many items we have
        var newForm = eventsPrototype.replace(/__name__/g, index);

        // increase the index with one for the next item
        $eventsHolder.data('index', index + 1);

        // Display the form in the page in an li, before the "Add a tag" link li
        var $newFormLi = $('<li></li>').append(newForm);
            $newLinkLi.before($newFormLi);
        }

当提交表单时,这是 AJAX 调用:

ajaxObject = {
  url: $("#postform").attr("action"),
  type: 'POST',
  dataType: 'json',
  xhrFields: {
    withCredentials: true
  },
  crossDomain: true,
  data: $("#postform").serialize()
};

$.ajax(ajaxObject)
  .success(function(data, status, xhr) {
    ...
  })
  .fail(function(data, status, xhr) {
    ...
  })
  .always(function(data, status, xhr) {
    ...
  });

假设我创建了两个事件。请注意,事件实体有两个字段,位置和时间(采用“时间”格式)。这是作为这些事件的数据发送的内容的示例:

[event][0][location]:Event A
[event][0][time]:22:22
[event][1][location]:Event B
[event][1][time]:22:11

在我的 Symfony REST Controller 内,我创建一个新的未命名表单来处理提交:

$form = $this->get('form.factory')->createNamed('', new AvRequestType(), $entity);
$form->handleRequest($request);

...validation and whatnot

更新:

尝试添加集合数组时,生产日志会产生以下错误:

"The Response content must be a string or object implementing __toString(), "array" given."

我知道这意味着我必须以某种方式将集合数组转换为字符串才能被 Symfony 接受。但如何呢?在将整个表单传递给 Symfony 之前,我已经通过 Javascript 序列化了整个表单。我想如果我在集合中有固定数量的项目,我可以 JSON.stringify() 每个表单字段,但这似乎不是一个非常优雅的解决方案。

最佳答案

解决这个问题的方法是表单需要有一个名称。

所以而不是...

$form = $this->get('form.factory')->createNamed('', new AvRequestType(), $entity);

...必须给出名称...

$form = $this->get('form.factory')->createNamed('myrequestform', new AvRequestType(), $entity);

这允许 Symfony(无论如何我假设)将所有字段识别为属于同一请求。因此,请求不要像这样:

eventDate:2016-02-01
pickupDate:2016-02-29 09:45:00
returnDate:2016-02-17 06:30:00
attendees:32
specialInstruction: special
[event][0][location]:LA
[event][0][time]:00:00
[event][1][location]:LB
[event][1][time]:11:11

现在看起来像这样:

avrequest[eventDate]:2016-02-01
avrequest[pickupDate]:2016-02-29 09:45:00
avrequest[returnDate]:2016-02-17 06:30:00
avrequest[attendees]:32
avrequest[specialInstruction]: sepcial
avrequest[event][0][location]:LA
avrequest[event][0][time]:00:00
avrequest[event][1][location]:LB
avrequest[event][1][time]:11:11

当您考虑如何在 Symfony 中提交表单时,这是有道理的;每个表单元素的名称属性的布局完全相同。

如果有人想添加比这更优雅的解释,请随意。

关于jquery - Symfony2 : Add Collection via AJAX Outside of Symfony,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35212373/

相关文章:

javascript - 为什么异步ajax请求不起作用?

jquery - Django + jQuery + Ajax

symfony - 文件上传中的错误消息自定义

php - 使 Doctrine 的 UniqueEntity 约束不区分大小写

javascript - 当值为法语名称时,jQuery 数据选项会 chop

jquery - 图像选择框而不是文本选择?

javascript - 使用 jqgrid 进行内联编辑。我卡住了

php - 如何保护 symfony2 中除登录页面之外的整个页面?

javascript - 页面加载后如何聚焦于输入字段?

javascript - 如何使用 jquery slider 过滤 ng-repeat 中的数据?