can.route
can.route
inherits: can.Map
Manage browser history and client state by synchronizing the window.location.hash with a can.Map.
can.route( template [, defaults] )
Create a route matching rule.
Parameters
-
template
{String}
the fragment identifier to match. The fragment identifier should start with either a character (a-Z) or colon (:). Examples:
can.route(":foo") can.route("foo/:bar")
-
defaults
{Object}
Optionalan object of default values
Use
Watch this video for an overview of can.route's functionality and an example showing how to connect two tab widgets to the browser's history:
In the following CanJS community we also talk about web application routing:
Background Information
To support the browser's back button and bookmarking in an Ajax application, most applications use the
window.location.hash
. By changing the hash (via a link or JavaScript), one is able to add to the browser's history without changing the page.This provides the basics needed to create history enabled Ajax websites. However,
can.route
addresses several other needs such as:How it works
can.route
is a can.Map that represents thewindow.location.hash
as an object. For example, if the hash looks like:the data in
can.route
looks like:can.route
keeps the state of the hash in-sync with thedata
contained withincan.route
.can.Map
can.route
is a can.Map. Understandingcan.Map
is essential for usingcan.route
correctly.You can listen to changes in an Observe with
bind(eventName, handler(ev, args...))
and change can.route's properties with attr.Listening to changes in can.route
Listen to changes in history by binding to changes in
can.route
like:attr
- the name of the changed attributehow
- the type of Observe change event (add, set or remove)newVal
/oldVal
- the new and old values of the attributeUpdating can.route
Create changes in the route data with attr like:
Or change multiple properties at once like:
When you make changes to can.route, they will automatically change the
hash
.Creating a Route
Use
can.route(url, defaults)
to create a route. A route is a mapping from a url to an object (that is the can.route's state). In order to map to a specific properties in the url, prepend a colon to the name of the property like:If no routes are added, or no route is matched, can.route's data is updated with the deparamed hash.
Once routes are added and the hash changes, can.route looks for matching routes and uses them to update can.route's data.
Default values can be added to a route:
Defaults can also be set on the root page of your app:
Initializing can.route
After your application has created all of its routes, call ready to set can.route's data to match the current hash:
Changing the route.
Typically, you don't set
location.hash
directly. Instead, you can change properties oncan.route
like:This will automatically look up the appropriate route and update the hash.
Often, you want to create links.
can.route
provides the link and url helpers to make this easy:Demo
The following demo shows the relationship between
## IE Compatibilitywindow.location.hash
, routes given tocan.data
,can.route
's data, and events oncan.data
. Most properties are editable so experiment!Internet Explorer 6 and 7 does not support
window.onhashchange
. Even Internet Explorer 8 running in IE7 compatibility mode reportstrue
foronhashchange
in window, even though the event isn't supported.If you are using jQuery, you can include Ben Alman's HashChange Plugin to support the event in the unsupported browser(s).
Using routes with
can.Control
Using templated event handlers, it is possible to listen to changes to
can.route
withincan.Control
. This is convenient as it allows the control to listen to and make changes whenever the route is modified, even outside of the control itself.Creating and binding routes with
can.Control.route
Using can.Control.route, a builtin plugin to CanJS, cuts down on the amount of code needed to work with
can.route
incan.Control
. With this plugin, it is possible to both create routes and bind tocan.route
at the same time. Instead of creating several routes to handle changes to type and id, write something like this in a control:Getting more specific with the
can.Map.delegate
pluginSometimes, you might only want to trigger a function when the route changes only once, even if the route change gets called multiple times. By using the delegate plugin, this is extremely easy. This plugin allows you to listen to change, set, add, and remove on
can.route
.If you wanted to, say, show a list of recipes when type was set to recipe and show a specific recipe when id was set, you could do something like:
If we didn't only listen to when recipe is set, then every time we chose to show a single recipe, we would create and show the list of recipes again which would not be very efficient.