Route Binding
One of the most common needs in a modern single page application is to facilitate a route/state change when clicking an element. An example of this would be a user clicking their profile page link in the header.
The easiest way of accomplishing this is via the route
binding.
Basic Route Binding¶
<router module="Router"> <a href="/profile" data-bind="route">Profile</a> </router>
When a route
binding is triggered it will traverse the DOM tree upwards until it finds its nearest parent router. It will then initiate the state change to the newly addressed route/state.
Note
-
By default the
route
binding will retrieve its destination url from thehref
property of the element it is attached to and triggers off of the click event.You can alter these defaults (and more) by providing a binding options configuration.
-
Any element can be bound to a route...it does not have to be an anchor tag.
Binding Lifecycle¶
When Footwork encounters a route
binding:
-
The binding is initialized.
If no binding options object is provided then:
-
The element is inspected and its
href
property is used as theurl
value -
Its handler is bound against the click event on the element.
-
-
If the element is an anchor tag, then its
href
attribute is set to theurl
value. -
The binding is now active until the element is removed from the DOM. It will respond to the configured event on the element.
-
Anytime the event is triggered, its nearest parent router state is changed per the route binding configuration.
The method defined by the history option (pushState/replaceState) on the route binding is the one used to manipulate the route.
-
The element is removed from the DOM, its handler is unsubscribed from the event and the binding is disposed of.
Binding Options¶
There are several options available when binding a route with an options object:
- state (string | object)
- on (string)
- activeClass (string | callback)
- history (string | callback)
- handler (callback)
Callback Binding and Context
Binding a callback operates on the local context.
This means that when you bind a callback/handler in your DOM it will be binding against the local view model the element is bound against, which is not necessarily the parent router (the router is likely/usually higher in the DOM tree).
state (string | object)¶
The state written to the routers currentState (as well as browser history) when the user triggers the binding.
String Value¶
<a data-bind="route: '/profile'">Profile</a>
Object¶
<a data-bind="route: { state: '/profile' }">Profile</a>
Note
If this value is provided as a string it will be used to set the element href
attribute value.
Search engines will then be able to use this when indexing the document. This also means users will be able to hover their mouse over to inspect, right-click to open in new window, or copy/paste any route
bound link (just as they would any other normal link).
on (string)¶
You can specify a different event upon which the binding is bound/triggered (default is click
):
<a data-bind="route: { on: 'dblclick' }" href="/profile">Profile</a>
activeClass (string | callback)¶
Any element bound to the currently active route will have this class applied to it. The default being: active
String Value¶
<a data-bind="route: { activeClass: 'active' }" href="/profile">Profile</a>
Callback Function¶
You can also provide a callback function which returns the class to use:
<a data-bind="route: { activeClass: active }" href="/profile">Profile</a>
viewModel.active = function () { return 'is-active'; }
This callback is triggered anytime the active route changes and matches the bound url (or when the element is initially bound, if the route already matches upon initialization).
history (string | callback)¶
By default a pushState
call is made when the binding is triggered. You can alter this by providing either push
or replace
with this value.
String Value¶
<a data-bind="route: { history: 'replace' }" href="/profile">Profile</a>
Callback Function¶
If you provide a callback function, its return value will be used to tell Footwork which history method to use:
<a data-bind="route: { history: whichHistory }" href="/profile">Profile</a>
The callback is provided the browser event used to trigger the binding along with the destination url:
self.whichHistory = function (event, url) { return 'replace'; }
This callback is evaluated whenever the binding is triggered.
handler (callback)¶
The handler called whenever the on event is triggered:
<a data-bind="route: { handler: goToProfile }" href="/profile">Profile</a>
This handler should return true or false, indicating whether or not the click is valid and should be routed to. Think of the callback as a predicate function for the route.
The callback is provided the browser event used to trigger the binding along with the destination url:
self.goToProfile = function (event, url) { // preventDefault prevents the browser from loading the new url event.preventDefault(); if (url === '/profile' && isLoggedIn) { return true; // route controller will be executed } else { return false; // nothing will happen } };
You can also return a url to route to from the callback:
self.goToProfile = function (event, url) { // preventDefault prevents the browser from loading the new url event.preventDefault(); if (url === '/profile' && isLoggedIn) { return '/profile-page'; // set the state and route to /profile-page (as opposed to /profile) } else { return false; // nothing will happen } };