Je travaille sur un projet utilisant Symfony 2, j'ai construit un ensemble pour gérer tous mes services de base de données qui transfère les données JSON en arrière.
Mon problème/question:
Est-il possible de poster un objet JSON directement? Actuellement, je parodie un message de formulaire normal pour mes appels ajax en attribuant un nom à l'objet json={"key":"value"}
. Si je ne le nomme pas, il semble impossible d'obtenir les données de l'objet de demande Symfony $JSON = $request->request->get('json');
Je souhaite pouvoir utiliser le même ensemble de services pour gérer les deux données provenant d'appels AJAX, ou d'un formulaire Symfony normal. Actuellement, je prends le formulaire Symfony soumis. JSON_ENCODE, je ne sais pas comment envoyer les données à mon contrôleur de services qui attend des données de demande.
Pour résumer:
Je souhaite que Symfony accepte un objet publication JSON plutôt qu'un formulaire.
Je souhaite transmettre l'objet JSON entre des contrôleurs à l'aide de Request/Response
Si je me trompe complètement, n'hésitez pas à me le dire!
Si vous souhaitez récupérer dans votre contrôleur des données envoyées en tant que JSON standard dans le corps de la demande, vous pouvez procéder de la manière suivante:
public function yourAction()
{
$params = array();
$content = $this->get("request")->getContent();
if (!empty($content))
{
$params = json_decode($content, true); // 2nd param to get as array
}
}
Maintenant $params
Sera un tableau complet de vos données JSON. Supprimez la valeur du paramètre true
dans l'appel json_decode()
pour obtenir un objet stdClass
.
J'ai écrit la méthode pour obtenir le contenu sous forme de tableau
protected function getContentAsArray(Request $request){
$content = $request->getContent();
if(empty($content)){
throw new BadRequestHttpException("Content is empty");
}
if(!Validator::isValidJsonString($content)){
throw new BadRequestHttpException("Content is not a valid json");
}
return new ArrayCollection(json_decode($content, true));
}
Et j'utilise cette méthode comme indiqué ci-dessous
$content = $this->getContentAsArray($request);
$category = new Category();
$category->setTitle($content->get('title'));
$category->setMetaTitle($content->get('meta_title'));
javascript sur la page:
function submitPostForm(url, data) {
var form = document.createElement("form");
form.action = url;
form.method = 'POST';
form.style.display = 'none';
//if (typeof data === 'object') {}
for (var attr in data) {
var param = document.createElement("input");
param.name = attr;
param.value = data[attr];
param.type = 'hidden';
form.appendChild(param);
}
document.body.appendChild(form);
form.submit();
}
après un événement (comme un clic sur "submit"):
// products is now filled with a json array
var products = jQuery('#spreadSheetWidget').spreadsheet('getProducts');
var postData = {
'action': action,
'products': products
}
submitPostForm(jQuery('#submitURLcreateorder').val(), postData);
dans le contrôleur:
/**
* @Route("/varelager/bestilling", name="_varelager_bestilling")
* @Template()
*/
public function bestillingAction(Request $request) {
$products = $request->request->get('products', null); // json-string
$action = $request->request->get('action', null);
return $this->render(
'VarelagerBundle:Varelager:bestilling.html.twig',
array(
'postAction' => $action,
'products' => $products
)
);
}
dans le modèle (bestilling.html.twig dans mon cas):
{% block resources %}
{{ parent() }}
<script type="text/javascript">
jQuery(function(){
//jQuery('#placeDateWidget').placedate();
{% autoescape false %}
{% if products %}
jQuery('#spreadSheetWidget').spreadsheet({
enable_listitem_amount: 1,
products: {{products}}
});
jQuery('#spreadSheetWidget').spreadsheet('sumQuantities');
{% endif %}
{% endautoescape %}
});
</script>
{% endblock %}
Alrite, je pense que c'est ce que tu voulais :)
EDIT Pour envoyer quelque chose sans simuler de formulaire, vous pouvez utiliser jQuery.ajax (). Voici un exemple dans le même esprit que ci-dessus qui ne déclenchera pas d'actualisation de page.
jQuery.ajax({
url: jQuery('#submitURLsaveorder').val(),
data: postData,
success: function(returnedData, textStatus, jqXHR ){
jQuery('#spreadSheetWidget').spreadsheet('clear');
window.alert("Bestillingen ble lagret");
// consume returnedData here
},
error: jQuery.varelager.ajaxError, // a method
dataType: 'text',
type: 'POST'
});