web-dev-qa-db-fra.com

Jouer 2.x: Comment faire une demande AJAX avec un bouton commun

J'ai donc réussi à obtenir des requêtes ajax pour travailler auparavant, mais j'ai toujours dû utiliser un formulaire, puis à la fin de la soumission, renvoyez false afin qu'il ne rafraîchisse pas la page.

J'ai également récemment déplacé mon javascript dans un fichier séparé, ce qui a provoqué l'échec de mes commandes @. Pour cette raison, je ne sais pas comment définir mon URL sur mon itinéraire?

Html:

<button id="saveAsDefaultButton">Save as default</button>

Playframework Java code:

public static Result saveDefaultPhoneForUser(String handset) {
    User currentUser = User.findByName(session("name"));
    currentUser.lastControlledHandset = theHandset;
    currentUser.save();
    return ok();
}

itinéraires:

POST    /                           controllers.Application.saveDefaultPhoneForUser(handset : String)

javascript:

$('#saveAsDefaultButton').click(function(evt) {
        $('#errors').hide();
        $.ajax({
            type : 'POST',
            url : "controllers.Application.saveDefaultPhoneForUser",
            data : $('#controlledPhone option:selected').text(),
            dataType : "text",
            success : function(data) {
                //setError('Call succedded');
                //$('#test1').attr("src", data)
            },
            error : function(data) {
                setError('Make call failed');
            }
        });
        return false;
    });

Je suis sûr qu'il existe un moyen de le faire, je n'ai tout simplement pas de chance de trouver quoi que ce soit. Toute aide grandement appréciée.

59
user1434177

Pour ce travail, vous devez utiliser javascriptRoutes car il génère des chemins JS corrects en fonction de votre routes.conf. Vous trouverez un exemple d'utilisation dans Zentask exemple

Quoi qu'il en soit, pour l'instant, vous pouvez corriger votre AJAX appel en changeant le url en

url : '@routes.Application.saveDefaultPhoneForUser()',

De cette façon, il doit placer l'intégralité du JS dans le modèle, ce qui est faux. Il peut ou même devrait être déplacé vers un fichier JS distinct et pour le rendre possible, vous devez utiliser javascriptRoutes.

Plus ...

javascriptRoutes ne sont pas décrits pourtant dans la documentation officielle, mais voici une introduction étape par étape. Bien que la description semble sophistiquée de facto l'utilisation de cette façon apporte de nombreux avantages.

1. Créez les itinéraires communs

Vous devez d'abord créer des itinéraires communs dans le fichier conf/routes:

GET     /item/:id     controllers.Application.getItem(id: Long)
POST    /item/new     controllers.Application.newItem
PUT     /item/:id     controllers.Application.updateItem(id: Long)

Bien sûr, vous devez créer au moins ces trois actions dans le contrôleur Application:

  • getItem(Long id){ ... }
  • newItem() { ... }
  • updateItem(Long id) { ... }

2. Créez une action traduisant les routes communes vers JS

  • placez-le quelque part, ie. dans votre contrôleur Application
  • Appelons ça javascriptRoutes()

Dans cette action, vous pointerez les routes existantes du fichier conf/routes

public static Result javascriptRoutes() {
    response().setContentType("text/javascript");
    return ok(
        Routes.javascriptRouter("myJsRoutes",
            routes.javascript.Application.getItem(),
            routes.javascript.Application.newItem(),
            routes.javascript.Application.updateItem(),
            //inside somepackage
            controllers.somepackage.routes.javascript.Application.updateItem()
        )
    );
}

Remarque: Ne définissez aucun paramètre entre crochets.

3. Créez un itinéraire pour l'action javascriptRoutes et incluez-le dans votre modèle

Route conf/routes

GET     /javascriptRoutes     controllers.Application.javascriptRoutes

Afficher dans <head> Une partie de /views/main.scala.html

<script type="text/javascript" src='@routes.Application.javascriptRoutes()'></script>

4. Utilisez javascriptRoutes où vous voulez

À partir de maintenant, vous pouvez utiliser des routes dans JS pour obtenir le chemin correct sans avoir besoin de spécifier url et type. Pour un exemple au lieu de:

 $('.getAjaxForThisContainer').click(function(e) {
    var idToGet = $("#someField").val();
    $.ajax({
        type : 'GET',
        url : '@routes.Application.getItem()',
        data : {
            id: idToGet
        },
        success : function(data) {
            // ... some code on success
        }
    });
    return false;
});

vous pouvez utiliser une version simplifiée (myJsRoutes à partir du point 2):

myJsRoutes.controllers.Application.getItem(idToGet).ajax({
    success : function(data) { ... some code ... }
});

ou

myJsRoutes.controllers.Application.newItem().ajax({
    success : function(data) { ... some code ... }
});

etc...

  • vous n'avez pas besoin de spécifier type: "POST" - Le routeur JS utilisera la bonne méthode selon la règle conf/routes
  • vous pouvez définir id de l'enregistrement (ou d'autres paramètres) sur GET ou PUT (ou d'autres méthodes) en utilisant la syntaxe routes-like en JS pur
  • Si votre règle d'itinéraire contient tous les paramètres requis, vous pouvez vraiment minimiser le vôtre JS:

pour l'itinéraire:

GET   /some/:a/:b/:c    controllers.Application.getABC(a: String, b: Integer, c: String)

JS:

myJsRoutes.controllers.Application.getABC("a", 1, "b" ).ajax({});
123
biesior

J'aime le "vieux bon" moyen simple:

1 Dans la page, avec JQuery,

à l'intérieur d'un même gestionnaire

 $.get('/giveme', {'arg': value}, function(data) {

                                    window.alert(data);

                                  }
 );

2 Côté serveur/lecture

2.1 Itinéraires: GET /giveme controllers.Application.giveme(arg)

2.2 scala action:

object Application extends Controller { 

      def giveme(arg:String) = Action {
        Ok(Json.toJson("hello," + arg ))
      }

    }
8
ses

Quelque chose à surveiller ... lors de l'appel

Routes.javascriptRouter("myJsRoutes",

Les itinéraires sont importés de play.Routes, pas play.api.Routes

J'ai eu une erreur lorsque j'ai implémenté ce code, car j'ai supposé qu'il proviendrait de l'API (j'avais clairement tort). A part ça, tout fonctionne très bien ~ !!

7
hook38

Il existe une solution plus simple, utilisez un routeur intégré pour générer un routeur Javascript. Vous pouvez générer un routeur Javascript en utilisant la directive d'assistance @javascriptRouter, Placez le code suivant à l'intérieur de votre balise de tête de page html (peut-être à l'intérieur du modèle de décoration principal)

<head>
    <title>Saeed Title</title>
    <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
    <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
    <script src="@routes.Assets.at("javascripts/jquery/v1.12.4/jquery.min.js")" type="text/javascript"></script>
    @helper.javascriptRouter("jsRoutes")(
        routes.javascript.MyController.getById,
        routes.javascript.MyController.getByName
    )
</head>

Ne vous inquiétez pas des erreurs de syntaxe (dans Intellij) et n'utilisez pas de parenthèses après le nom de votre action. Vous pouvez maintenant utiliser jsRoutes.controllers.MyController.getById(id) dans votre code d'appel ajax.

$.ajax(jsRoutes.controllers.MyController.getById(id))
   .done( /*...*/ )
   .fail( /*...*/ );

ou utilisez jsRoutes.controllers.MyController.getById(id).url pour obtenir l'url. plus d'informations .

2
Saeed Zarinfam

La réponse de Marcus est très bonne, donc toute autre personne ayant ce problème devrait pouvoir l'utiliser.

Cependant, j'ai eu un problème en essayant de faire fonctionner cela, ce qui m'a pris un peu de temps pour travailler. Lorsque je faisais ma demande ajax, elle était acheminée vers la mauvaise méthode.

En effet, dans mon fichier de routes, j'avais les éléments suivants:

POST    /                           controllers.Application.makeCall()
POST    /                           controllers.Application.saveDefaultPhoneForUser(handset : String)

En ayant deux méthodes de publication avec le même emplacement /. Il semblait toujours aller appeler. Donc, juste un conseil pour quiconque ne le fait pas, sinon cela ne fonctionnera pas.

Je devais juste le changer pour:

POST    /                           controllers.Application.makeCall()
POST    /saveDefaultPhoneForUser    controllers.Application.saveDefaultPhoneForUser(handset : String)

J'espère que cela aide quelqu'un.

1
user1434177