it-swarm.com.de

Play 2.x: Wie erstelle ich eine AJAX Anfrage mit einem gemeinsamen Button?

So habe ich erfolgreich Ajax-Anfragen erhalten, um zu arbeiten, aber ich musste immer ein Formular verwenden, und dann am Ende des Submit-Vorgangs false zurückgeben, damit die Seite nicht aktualisiert wird.

Ich habe auch erst kürzlich mein Javascript in eine separate Datei verschoben, was dazu geführt hat, dass meine @ -Befehle fehlgeschlagen sind. Aus diesem Grund weiß ich nicht, wie ich meine URL auf meine Route einstellen soll?

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();
}

routen:

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;
    });

Ich bin mir sicher, dass es einen Weg gibt, dies zu tun. Ich habe einfach kein Glück, etwas zu finden. Jede Hilfe sehr geschätzt.

59
user1434177

Für diesen Job sollten Sie javascriptRoutes verwenden, da es basierend auf Ihrer routes.conf korrekte JS-Pfade generiert. Sie finden Anwendungsbeispiel in Zentask sample

Wie auch immer, jetzt können Sie Ihren AJAX) - Aufruf korrigieren, indem Sie url in ändern

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

Auf diese Weise muss das gesamte JS in der Vorlage platziert werden, was falsch ist. Es kann oder sollte sogar in eine separate JS-Datei verschoben werden. Um dies zu ermöglichen, müssen Sie JavascriptRoutes verwenden.

Mehr ...

javascriptRoutes werden nicht beschrieben noch in der offiziellen Dokumentation, aber hier ist eine schrittweise Einführung. Obwohl die Beschreibung raffiniert aussieht, bringt de facto die Verwendung dieser Methode viele Vorteile.

1. Erstellen Sie die gemeinsamen Routen

Zuerst müssen Sie gemeinsame Routen in der Datei conf/routes Erstellen:

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

Natürlich müssen Sie mindestens diese drei Aktionen in Application controller erstellen:

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

2. Erstellen Sie eine Aktion, die allgemeine Routen nach JS übersetzt

  • platziere es irgendwo, dh. in Ihrem Application Controller
  • Nennen wir es javascriptRoutes()

In dieser Aktion verweisen Sie auf die vorhandenen Routen aus der Datei 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()
        )
    );
}

Hinweis: Setzen Sie keine Parameter in Klammern.

3. Erstellen Sie eine Route für die Aktion javascriptRoutes und fügen Sie sie Ihrer Vorlage hinzu

Route conf/routes

GET     /javascriptRoutes     controllers.Application.javascriptRoutes

In <head> Teil von /views/main.scala.html Anzeigen

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

4. Verwenden Sie JavascriptRoutes, wo Sie wollen

Ab sofort können Sie Routen in JS verwenden, um den richtigen Pfad zu ermitteln, ohne die Zeichen url und type angeben zu müssen. Für ein Beispiel anstelle von:

 $('.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;
});

sie können eine vereinfachte Version verwenden (myJsRoutes ab Punkt 2):

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

oder

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

etc...

  • sie müssen nicht type: "POST" angeben - Der JS-Router verwendet die richtige Methode gemäß der Regel conf/routes
  • sie können id des Datensatzes (oder anderer Parameter) mit der Syntax routes-like in Pure JS auf GET oder PUT (oder andere Methoden) setzen
  • Wenn Ihre Routenregel alle erforderlichen Parameter enthält, können Sie Ihre JS wirklich minimieren:

für die Route:

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

Ich mag "alt gut" auf einfache Weise:

1 In der Seite mit JQuery,

in einem Even-Handler

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

                                    window.alert(data);

                                  }
 );

2 Auf der Server-/Spielseite

2.1 Routen: 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

Etwas, auf das Sie achten müssen, wenn Sie anrufen

Routes.javascriptRouter("myJsRoutes",

Routen werden aus play.Routes importiert, nicht aus play.api.Routes

Bei der Implementierung dieses Codes ist ein Fehler aufgetreten, da ich davon ausgegangen bin, dass er von api stammt (ich habe mich eindeutig geirrt). Ansonsten funktioniert alles super ~ !!

7
hook38

Es gibt eine einfachere Lösung: Verwenden Sie Embedded Router, um Javascript-Router zu generieren. Sie können den JavaScript-Router mit der Hilfsanweisung @javascriptRouter Erstellen. Fügen Sie den folgenden Code in das HTML-Seitenkopf-Tag ein (möglicherweise in die Hauptdekorationsvorlage).

<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>

Machen Sie sich keine Gedanken über Syntaxfehler (in Intellij) und verwenden Sie keine Klammern nach Ihrem Aktionsnamen. Jetzt können Sie jsRoutes.controllers.MyController.getById(id) in Ihrem Ajax-Aufrufcode verwenden.

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

oder benutze jsRoutes.controllers.MyController.getById(id).url um die URL zu erhalten. weitere Informationen .

2
Saeed Zarinfam

Die Antwort von Marcus ist sehr gut, daher sollte jeder, der dieses Problem hat, in der Lage sein, dies zu verwenden.

Ich hatte jedoch ein Problem, als ich versuchte, dies zum Laufen zu bringen, was mich eine Weile gekostet hat. Als ich meine Ajax-Anfrage stellte, wurde sie auf die falsche Methode umgeleitet.

Das lag daran, dass ich in meiner Routendatei Folgendes hatte:

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

Durch zwei Postmethoden mit demselben Standort. Es schien immer zu gehen, um einen Anruf zu tätigen. Also nur ein Tipp für alle, tut dies nicht, sonst funktioniert es nicht.

Ich musste es nur ändern in:

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

Hoffe das hilft jemandem.

1
user1434177