Игра 2.x: Как сделать запрос AJAX с общей кнопкой
Итак, я успешно получил ajax-запросы для работы раньше, но мне всегда приходилось использовать форму, а затем в конце submit do возвращать false, чтобы он не обновлял страницу.
Я также недавно перевел мой javascript в отдельный файл, из-за чего мои @команды терпят неудачу. Из-за этого я не знаю, как установить свой URL-адрес на мой маршрут?
Html:
<button id="saveAsDefaultButton">Save as default</button>
Код java java:
public static Result saveDefaultPhoneForUser(String handset) {
User currentUser = User.findByName(session("name"));
currentUser.lastControlledHandset = theHandset;
currentUser.save();
return ok();
}
маршруты:
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;
});
Я уверен, что есть способ сделать это, мне просто нечего найти. Любая помощь значительно ускользает.
Ответы
Ответ 1
Для этого задания вы должны пойти с javascriptRoutes
, поскольку он генерирует правильные пути JS на основе ваших маршрутов .conf. Вы найдете образец использования в Zentask sample
В любом случае, на данный момент вы можете исправить свой вызов AJAX, изменив url
на
url : '@routes.Application.saveDefaultPhoneForUser()',
Этот способ требует, чтобы он помещал все JS в шаблон, что неверно. Он может или даже должен быть перемещен в отдельный JS файл и чтобы вы могли использовать javascriptRoutes.
Подробнее...
javascriptRoutes не описаны еще в официальной документации, но здесь пошаговое введение в нее. Хотя описание выглядит сложным де-факто, используя этот способ, приносит много преимуществ.
1. Создание общих маршрутов
Сначала вам нужно создать общие маршруты в файле conf/routes
:
GET /item/:id controllers.Application.getItem(id: Long)
POST /item/new controllers.Application.newItem
PUT /item/:id controllers.Application.updateItem(id: Long)
Конечно, вам нужно создать по крайней мере эти три действия в контроллере Application
:
-
getItem(Long id){ ... }
-
newItem() { ... }
-
updateItem(Long id) { ... }
2. Создайте действие, переводящее общие маршруты в JS
- поместите его где-нибудь, т.е. в вашем контроллере
Application
- Позвоните ему
javascriptRoutes()
В этом действии вы укажете маршруты существующий из файла 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()
)
);
}
Примечание: Не устанавливайте никаких параметров в скобках.
3. Создайте маршрут для действия javascriptRoutes
и включите его в свой шаблон
Маршрут conf/routes
GET /javascriptRoutes controllers.Application.javascriptRoutes
Просмотр в <head>
части /views/main.scala.html
<script type="text/javascript" src='@routes.Application.javascriptRoutes()'></script>
4. Используйте javascriptRoutes, где вы хотите
Теперь вы можете использовать маршруты в JS для получения правильного пути, не указывая url
и type
. Для примера вместо:
$('.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;
});
вы можете использовать упрощенную версию (myJsRoutes
из пункта 2):
myJsRoutes.controllers.Application.getItem(idToGet).ajax({
success : function(data) { ... some code ... }
});
или
myJsRoutes.controllers.Application.newItem().ajax({
success : function(data) { ... some code ... }
});
и т.д...
- вам не нужно указывать
type: "POST"
- JS-маршрутизатор будет использовать правильный метод согласно правилу conf/routes
- вы можете установить
id
записи (или других параметров) на GET
или PUT
(или другие методы), используя синтаксис routes-like
в чистом JS
- Если ваше правило маршрута содержит все необходимые параметры, вы действительно можете свести к минимуму ваш JS:
для маршрута:
GET /some/:a/:b/:c controllers.Application.getABC(a: String, b: Integer, c: String)
JS:
myJsRoutes.controllers.Application.getABC("a", 1, "b" ).ajax({});
Ответ 2
Что-то, на что нужно обратить внимание... при вызове
Routes.javascriptRouter("myJsRoutes",
Маршруты импортируются из play.Routes, а не play.api.Routes
Была ошибка, когда я реализовал этот код, потому что я предположил, что это произойдет из api (очевидно, я был неправ).
Кроме этого, все отлично работает ~!!
Ответ 3
Мне нравится "старый добрый" простой способ:
1 На странице с JQuery
внутри некоторого четного обработчика
$.get('/giveme', {'arg': value}, function(data) {
window.alert(data);
}
);
2 На стороне сервера/воспроизведения
2.1 Маршруты: GET /giveme controllers.Application.giveme(arg)
2.2 scala действие:
object Application extends Controller {
def giveme(arg:String) = Action {
Ok(Json.toJson("hello," + arg ))
}
}
Ответ 4
Существует более простое решение, используйте встроенный маршрутизатор для создания Javascript-маршрутизатора. Вы можете создать Javascript-маршрутизатор, используя директиву @javascriptRouter
helper, поместите следующий код внутри своего тега заголовка html-страницы (возможно, внутри основного шаблона украшения)
<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>
Не беспокойтесь о синтаксической ошибке (в Intellij) и не используйте круглые скобки после имени вашего действия.
Теперь вы можете использовать jsRoutes.controllers.MyController.getById(id)
в своем кодовом коде ajax.
$.ajax(jsRoutes.controllers.MyController.getById(id))
.done( /*...*/ )
.fail( /*...*/ );
или используйте jsRoutes.controllers.MyController.getById(id).url
для получения URL-адреса.
дополнительная информация.
Ответ 5
Ответ Маркуса очень хорош, поэтому любой, кто имеет эту проблему, должен иметь возможность использовать это.
У меня была одна проблема, хотя, пытаясь заставить ее работать, и мне потребовалось немного времени, чтобы работать. Когда я делал свой запрос ajax, он маршрутизировал неправильный метод.
Это было связано с тем, что в файле маршрутов у меня было следующее:
POST / controllers.Application.makeCall()
POST / controllers.Application.saveDefaultPhoneForUser(handset : String)
Имея два метода сообщения с одинаковым местоположением /. Казалось, что всегда нужно звонить. Так что просто совет для тех, кто не делает этого, иначе он не будет работать.
Мне просто нужно было изменить его на:
POST / controllers.Application.makeCall()
POST /saveDefaultPhoneForUser controllers.Application.saveDefaultPhoneForUser(handset : String)
Надеюсь, это поможет кому-то.