2016-03-07 30 views
1

我們有一箇舊網站,我已經實現了一個由AngularJS發送給PHP腳本並在處理完電子郵件後發送的表單。如果表單無效,PHP腳本將返回一個帶有驗證錯誤的JSON。由於我們已經在一些其他應用程序(REST API)中使用Symfony,所以我認爲在Symfony中重新實現我的普通PHP腳本會很好。Symfony2:通過AJAX手動提交沒有類的表單

爲了簡單起見,我只放了一小段但相關的代碼片段。這是我有:

<form name="infoscreenForm" class="form-horizontal" enctype="multipart/form-data" ng-controller="FormController"> 
    <div class="form-group"> 
     <div class="col-lg-1 control-label">*</div> 
     <div class="col-lg-11 input-group"> 
      <input type="text" class="form-control" id="contact_person" 
        name="contact_person" ng-model="formData.contactPerson" 
        placeholder="Kontaktperson"> 
     </div> 
     <span class="text-warning" ng-show="errors.contactPerson"> 
      {{ errors.contactPerson }} 
     </span> 
    </div> 
    <div class="form-group"> 
     <div class="col-lg-1 control-label">*</div> 
     <div class="col-lg-11 input-group"> 
      <span class="input-group-addon">@</span> 
      <input type="email" class="form-control" id="email" name="email" 
        ng-model="formData.email" placeholder="E-Mail"> 
     </div> 
     <span class="text-warning" ng-show="errors.email"> 
      {{ errors.email }} 
     </span> 
    </div> 
    <div class="form-group"> 
     <div class="col-lg-1 control-label">&nbsp;</div> 
     <div class="col-lg-11 input-group"> 
      <input type="file" class="form-control" id="file" name="file" 
        file-model="formData.file" 
        accept="application/pdf,image/jpeg,image/png"> 
     </div> 
     <span class="text-warning" ng-show="errors.file"> 
      {{ errors.file }} 
     </span> 
    </div> 
    <div class="form-group"> 
     <button type="submit" class="btn btn-default" id="submit" 
       name="submit" ng-click="submitForm()"> 
      Formular absenden 
     </button> 
    </div> 
</form> 

JS:

HTML(NG-應用程序是在body標籤,這裏沒有顯示約束)

var app = angular.module('InfoscreenApp', []); 

app.directive('fileModel', ['$parse', function ($parse) { 
    return { 
    restrict: 'A', 
    link: function (scope, element, attrs) { 
     var model = $parse(attrs.fileModel); 
     var modelSetter = model.assign; 

     element.bind('change', function() { 
     scope.$apply(function() { 
      modelSetter(scope, element[0].files[0]); 
     }); 
     }); 
    } 
    }; 
}]); 

app.factory('multipartForm', ['$http', function ($http) { 
    return { 
     post : function (uploadUrl, data) { 
     var fd = new FormData(); 
     for (var key in data) { 
      fd.append(key, data[key]); 
     } 
     return $http.post(uploadUrl, fd, { 
      transformRequest: angular.identity, 
      headers : { 'Content-Type': undefined } 

     }); 
     } 
    }; 
}]); 

app.controller('FormController', ['$scope', 'multipartForm', function ($scope, multipartForm) { 
    $scope.formData = {}; 

    $scope.submitForm = function() { 
     var uploadUrl = 'http://localhost:8000/infoscreen'; 
     multipartForm.post(uploadUrl, $scope.formData) 
     .then(function (data) { 
     console.log(data); 

     if (data.success) { 
      $scope.message = data.data.message; 
      console.log(data.data.message); 
     } else { 
      $scope.errors = data.data.errors; 
     } 
     }); 
    }; 
}]); 

全部用純PHP腳本一切工作正常。以下是我試過的Symfony做:

<?php 

namespace AppBundle\Controller; 

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\Form\Extension\Core\Type\TextType; 
use Symfony\Component\Form\Extension\Core\Type\EmailType; 
use Symfony\Component\Form\Extension\Core\Type\FileType; 
use Symfony\Component\Form\Extension\Core\Type\SubmitType; 
use Symfony\Component\Validator\Constraints\NotBlank; 
use Symfony\Component\Validator\Constraints\Email; 

class DefaultController extends Controller 
{ 
    /** 
    * @Route("/infoscreen", name="infoscreen") 
    */ 
    public function infoscreenAction(Request $request) 
    { 
     $defaultData = array('message' => 'infoscreenForm'); 
     $form = $this->createFormBuilder($defaultData) 
      ->add('contactPerson', TextType::class, array(
       'constraints' => array(
        new NotBlank(), 
       ) 
      )) 
      ->add('email', EmailType::class, array(
       'constraints' => array(
        new NotBlank(), 
        new Email(), 
       ) 
      )) 
      ->add('file', FileType::class) 
      ->add('submit', SubmitType::class) 
      ->getForm(); 
     ; 

     $form->submit($request->request->get($form->getName())); 
     $data = $form->getData(); 

     if ($form->isValid()) { 
      echo 'Alles ok'; 
      // send an email 
     } 

     $errors = array(); 
     $validation = $this->get('validator')->validate($form); 
     foreach ($validation as $error) { 
      $errors[$error->getPropertyPath()] = $error->getMessage(); 
     } 

     $response = new Response(); 
     $response->setContent(json_encode(array(
      'form_data' => $data, 
      'errors' => $errors, 
     ))); 
     $response->headers->set('Content-Type', 'application/json'); 

     return $response; 
    } 
} 

CSRF在config.yml禁用。表單沒有綁定到實體類。提交表格後,我在控制檯中的下列對象:

{ 
    data: Object, 
    status: 200, 
    config: Object, 
    statusText: "OK" 
} 

的重要組成部分,是data: Object

{ 
    form_data: { 
     contactPerson: null, 
     email: null, 
     message: "infoscreenForm", 
     file: null 
    }, 
    errors : { 
     children[contactPerson].data = "This value should not be blank", 
     children[email].data = "This value should not be blank" 
    } 
} 

這發生在我提交表單,在字段中輸入一些值。看起來提交的數據沒有綁定到控制器中的表單。我可能錯過了一些東西,但我卡在這裏,不知道如何繼續。我試着用$form->bind($request),$form->handleRequest($request)和其他一些東西,但它沒有奏效。即使我單獨綁定這些字段,我仍然沒有在表單中獲得它們的值。

有人可以幫我。

在此先感謝。

回答

2

嘗試

$this->get('form.factory')->createNamedBuilder(null, 'form', $defaultData) 

,而不是

$this->createFormBuilder($defaultData) 
+0

是的,這樣做的伎倆。我還必須用'$ form-> bind($ request)'綁定表單,現在我得到了這些值。非常感謝你! большоеспасибо! – cezar