Using the JavaScript reverse router

There is a major issue with the preceding JavaScript code; the way it computes the URL of the Items.delete route is very fragile because it duplicates the route definition:

xhr.open('DELETE', '/items/' + btn.dataset.id);

If you change the route definition, you will also have to accordingly change the preceding line of code.

We can solve this issue by putting the route information in the HTML attributes, instead of putting the item ID, as follows:

<li>
  <a href="@routes.Items.details(item.id)">@item.name</a>
  @defining(routes.Items.delete(item.id)) { route =>
  <button class="delete-item"
            data-url="@route.url"
            data-method="@route.method">Delete</button>
  }
</li>

However, in practice, this approach does not scale; in practice, you often need to compute URLs from the client side. Fortunately, this is exactly what the JavaScript reverse router does.

Play provides a JavaScript reverse router: a JavaScript program that computes your route URLs from their corresponding action parameters. For instance, the URL of the Items.delete action can be computed from an item ID as follows, assuming that the JavaScript reverse router is available through a global routes object:

var itemId = btn.dataset.id;
var route = routes.controllers.Items.delete(itemId);
xhr.open(route.method, route.url);

The routes object contains properties that correspond to your routes' (fully qualified) names. Each route has a corresponding function (here, the controllers.Items.delete function) that returns an object with the method and url properties corresponding to the HTTP verb and URL to be used, respectively.

For the previous code to work, you actually need to define this routes object that contains the JavaScript reverse router. You can do this by defining an HTTP endpoint that returns a JavaScript document which defines a routes object containing the reverse router. Start by updating the layout template so that all pages include the JavaScript reverse router:

<script src="@routes.Application.javascriptRouter()"></script>

Put the preceding line before you load any other script of your application. Then, define the corresponding javascriptRouter action and add a route for it:

import play.api.Routes
def javascriptRouter = Action { implicit request =>
  Ok(Routes.javascriptRouter("routes")(
  routes.javascript.Items.delete
  ))
}

The action definition uses the play.api.Routes.javascriptRouter method that takes an identifier (here, routes) and a list of JavaScript routes (here, just routes.javascript.Items.delete) and returns a JavaScript program containing the reverse router. The routes.javascript namespace is generated by Play from your routes file.

In Java, the equivalent action will be the following:

import play.Routes;
public static Result javascriptRouter() {
  return ok(Routes.javascriptRouter("routes",
  routes.javascript.Items.delete()));
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.77.158