diff --git a/doc/can-route.md b/doc/can-route.md index 16428cd..b66e471 100644 --- a/doc/can-route.md +++ b/doc/can-route.md @@ -16,25 +16,22 @@ the can-route export: ```js - { - data, // The bound observable. - register, // Register routes that translate between - // the url and the bound observable. - start, // Begin updating the bound observable with - // url data and vice versa. - - deparam, // Given url fragment, return the data for it. - rule, // Given url fragment, return the routing rule - - param, // Given data, return a url fragment. - url, // Given data, return a url for it. - link, // Given data, return an tag for it. - - isCurrent, // Given data, return true if the current url matches - // the data. - currentRule, // Return the matched rule name. - } - ``` +{ + data, // The bound observable. + register, // Register routes that translate between + // the url and the bound observable. + start, // Begin updating the bound observable with + // url data and vice versa. + deparam, // Given url fragment, return the data for it. + rule, // Given url fragment, return the routing rule + param, // Given data, return a url fragment. + url, // Given data, return a url for it. + link, // Given data, return an tag for it. + isCurrent, // Given data, return true if the current url matches + // the data. + currentRule // Return the matched rule name. +} +``` @body @@ -85,33 +82,31 @@ import route from "can-route"; import DefineMap from "can-define/map/map"; import stache from "can-stache"; import "can-stache-route-helpers"; - -Component.extend({ - tag: "my-app", - autoMount: true, - ViewModel: DefineMap.extend({ - page: "string" - }), - view: stache(` - {{#switch(page)}} - {{#case("home")}} -

Home Page

-
Products - {{/case}} - {{#case("products")}} -

Products

- Home - {{/case}} - {{#default()}} -

Page Not Found

- Home - {{/default}} - {{/switch}} - `) -}); - -route.data = document.querySelector("my-app"); -route.register("{page}"); +Component.extend( { + tag: "my-app", + autoMount: true, + ViewModel: DefineMap.extend( { + page: "string" + } ), + view: stache( ` +{{#switch(page)}} +{{#case("home")}} +

Home Page

+Products +{{/case}} +{{#case("products")}} +

Products

+Home +{{/case}} +{{#default()}} +

Page Not Found

+Home +{{/default}} +{{/switch}} +` ) +} ); +route.data = document.querySelector( "my-app" ); +route.register( "{page}" ); route.start(); ``` @@ -122,16 +117,14 @@ An observable can be set as `route.data` directly. The following sets `route.da to an `AppViewModel` instance: ```js -var DefineMap = require("can-define/map/map"); -var route = require("can-route"); - -var AppViewModel = DefineMap.extend({ - page: "string" -}); - -var appState = new AppViewModel(); +import DefineMap from "can-define/map/map"; +import route from "can-route"; +const AppViewModel = DefineMap.extend( { + page: "string" +} ); +const appState = new AppViewModel(); route.data = appState; -route.register('{page}', {page: 'home'}); +route.register( "{page}", { page: "home" } ); route.start(); ``` @@ -145,20 +138,21 @@ Listen to changes in the url by listening on the underlying route data. For exa your route data and rule might have a page property: ```js -var AppViewModel = DefineMap.extend({ - page: "string" -}); +const AppViewModel = DefineMap.extend( { + page: "string" +} ); route.data = new AppViewModel(); -route.register("{page}"); +route.register( "{page}" ); route.start(); ``` You can listen to when the url changes from `"#!recipes"` to `"#!settings"` with: ```js -route.data.on('page', function(ev, newVal, oldVal) { - // page changed from "recipes" to "settings" -}); +route.data.on( "page", function( ev, newVal, oldVal ) { + +// page changed from "recipes" to "settings" +} ); ``` ### Updating can-route @@ -166,13 +160,13 @@ route.data.on('page', function(ev, newVal, oldVal) { When using a [can-define/map/map DefineMap] to back can-route, create changes in the route data by modifying it directly: ```js -route.data.page = 'images'; +route.data.page = "images"; ``` Or change multiple properties at once like: ```js -route.data.update({page: 'tasks', id: 5}); +route.data.update( { page: "tasks", id: 5 } ); ``` When you make changes to can-route, they will automatically @@ -186,9 +180,10 @@ If the change in your route data includes a `/`, the `/` will be encoded into `% You will see this result in the URL and `location.hash`. ```js -route.data.type = 'image/bar'; +route.data.type = "image/bar"; + // OR -route.attr('type', 'image/bar'); +route.attr( "type", "image/bar" ); ``` The URL will look like this: @@ -208,7 +203,7 @@ In order to map to a specific properties in the url, prepend a colon to the name of the property like: ```js -route.register("#!content/{type}"); +route.register( "#!content/{type}" ); ``` If no routes are added, or no route is matched, @@ -217,6 +212,7 @@ hash. ```js location.hash = "#!type=videos"; + // route -> {type : "videos"} ``` @@ -225,18 +221,21 @@ can-route looks for matching routes and uses them to update can-route’s data. ```js -route.register("#!content/{type}"); +route.register( "#!content/{type}" ); location.hash = "#!content/images"; + // route -> {type : "images"} route.data.type = "songs"; + // location.hash -> "#!content/songs" ``` Default values can be added to a route: ```js -route.register("content/{type}",{type: "videos" }); -location.hash = "#!content/" +route.register( "content/{type}", { type: "videos" } ); +location.hash = "#!content/"; + // route -> {type : "videos"} // location.hash -> "#!content/" ``` @@ -244,8 +243,9 @@ location.hash = "#!content/" Defaults can also be set on the root page of your app: ```js -route.register("", { page: "index" }); +route.register( "", { page: "index" } ); location.hash = "#!"; + // route -> {page : "index"} // location.hash -> "#!" ``` @@ -266,7 +266,7 @@ directly. Instead, you can change properties on can-route like: ```js -route.data.type = 'videos'; +route.data.type = "videos"; ``` This will automatically look up the appropriate @@ -277,7 +277,7 @@ the [can-route.link] and [can-route.url] helpers to make this easy: ```js -route.link("Videos", {type: 'videos'}); +route.link( "Videos", { type: "videos" } ); ``` ## Finding the matched route @@ -292,24 +292,20 @@ The matched rule is stored in the compute `route.currentRule` and is used to set In order for a route to be matched, all of the map properties it uses must be set. For example, in the following route, `page` and `section` must be set in order for this route to be matched: ```js -route.register('{page}/{section}'); +route.register( "{page}/{section}" ); route.start(); - -route.data.page = 'contact'; -route.data.section = 'email'; - +route.data.page = "contact"; +route.data.section = "email"; route.currentRule(); // "{page}/{section}" ``` If a route contains default values, these map properties must also be set to match the default value in order for the route to be matched: ```js -route.register('{page}', { section: 'email' }); +route.register( "{page}", { section: "email" } ); route.start(); - -route.data.page = 'contact'; -route.data.section = 'email'; - +route.data.page = "contact"; +route.data.section = "email"; route.currentRule(); // "{page}" ``` @@ -318,13 +314,11 @@ route.currentRule(); // "{page}" If multiple routes have all of their properties set, the route with the highest number of set properties will be used: ```js -route.register('{page}'); -route.register('{page}/{section}'); +route.register( "{page}" ); +route.register( "{page}/{section}" ); route.start(); - -route.data.page = 'two'; -route.data.section = 'a'; - +route.data.page = "two"; +route.data.section = "a"; route.currentRule(); // "{page}/{section}" ``` @@ -333,12 +327,10 @@ route.currentRule(); // "{page}/{section}" If multiple routes are still matched, the route that was registered first will be matched: ```js -route.register('', { page: 'home' }); -route.register('{section}'); +route.register( "", { page: "home" } ); +route.register( "{section}" ); route.start(); - -route.data.page = 'home'; -route.data.section = 'a'; - +route.data.page = "home"; +route.data.section = "a"; route.currentRule(); // "" ``` diff --git a/doc/currentRule.md b/doc/currentRule.md index a73cc39..9a25eeb 100644 --- a/doc/currentRule.md +++ b/doc/currentRule.md @@ -12,12 +12,9 @@ Use `route.currentRule()` to find the current route rule. ```js -route("{type}", { type: "foo" }); -route("{type}/{subtype}"); - +route( "{type}", { type: "foo" } ); +route( "{type}/{subtype}" ); route.currentRule(); // "{type}" - route.data.subtype = "foo"; - route.currentRule(); // "{type}/{subtype}" ``` diff --git a/doc/data.md b/doc/data.md index 37f7900..9686a62 100644 --- a/doc/data.md +++ b/doc/data.md @@ -10,9 +10,8 @@ properties will update the hash and vice-versa. ```js import DefineMap from "can-define/map/map"; import route from "can-route"; - -route.data = new DefineMap({page: ""}); -route.register("{page}"); +route.data = new DefineMap( { page: "" } ); +route.register( "{page}" ); route.start(); ``` @@ -24,16 +23,14 @@ to the browser's hash. ```js import Component from "can-component"; import route from "can-route"; - -Component.extend({ +Component.extend( { tag: "my-app", autoMount: true, - ViewModel: { ... }, - view: { ... } -}) - -route.data = document.querySelector("my-app"); -route.register("{page}"); + ViewModel: { /* ... */ }, + view: { /* ... */ } +} ); +route.data = document.querySelector( "my-app" ); +route.register( "{page}" ); route.start(); ``` @@ -50,34 +47,31 @@ An elegant way to solve this problem is using the [Observer Pattern](http://en.w Setting `route.data` is an easy way to cross-bind your Application ViewModel object to `route`. This will serialize your Application ViewModel into the hash (or pushstate URLs). ```js -var ViewModel = DefineMap.extend({ +const ViewModel = DefineMap.extend( { petType: "string", storeId: "number" -}); - -var viewModel = new ViewModel({ +} ); +const viewModel = new ViewModel( { petType: "string", storeId: "number" -}); - +} ); route.data = viewModel; ``` `route.data` can also be set to a constructor function. A new instance will be created and bound to: ```js -var ViewModel = DefineMap.extend({ - page: { - type: "string", - set: function(page){ - if(page === "user") { - this.verifyLoggedIn(); - } - return page; - } - } -}); - +const ViewModel = DefineMap.extend( { + page: { + type: "string", + set: function( page ) { + if ( page === "user" ) { + this.verifyLoggedIn(); + } + return page; + } + } +} ); route.data = ViewModel; ``` @@ -98,71 +92,72 @@ The following example shows loading some metadata on page load, which must be lo It also shows an example of a "virtual" property on the AppViewModel, locationIds, which is the serialized version of a non-serializeable can.List, locations. A setter is defined on locationIds, which will translate changes in locationIds back to the locations can.List. ```js -var Location = DefineMap.extend({ +const Location = DefineMap.extend( { selected: "boolean", id: "any" -}); - -var LocationList = DefineList.extend({ +} ); +const LocationList = DefineList.extend( { "*": Location -}); - -var AppViewModel = DefineMap.extend({ +} ); +const AppViewModel = DefineMap.extend( { locations: { type: "any", + // don't serialize this property at all in the route serialize: false }, + // virtual property that contains a comma separated list of ids // based on locations that are selected locationIds: { // comma separated list of ids - serialize: function(){ - var selected = thislocations.filter( - function(location){ + serialize: function() { + const selected = thislocations.filter( + function( location ) { return location.selected; - }); - var ids = []; - selected.each(function(item){ - ids.push(item.id); - }) - return selected.join(','); + } ); + const ids = []; + selected.each( function( item ) { + ids.push( item.id ); + } ); + return selected.join( "," ); }, // toggle selected from a comma separated list of ids - set: function(val){ - var arr = val; - if(typeof val === "string"){ - arr = val.split(',') + set: function( val ) { + let arr = val; + if ( typeof val === "string" ) { + arr = val.split( "," ); } + // for each id, toggle any matched location - this.locations.forEach(function(location){ - if(arr.indexOf(location.id) !== -1){ + this.locations.forEach( function( location ) { + if ( arr.indexOf( location.id ) !== -1 ) { location.selected = true; } else { location.selected = false; } - }) + } ); } } -}); +} ); // initialize and set route.data first, so anything binding to can-route // will work correctly -var viewModel = new AppViewModel(); +const viewModel = new AppViewModel(); route.data = appViewModel; // GET /locations -var locations = new Location.List({}); +const locations = new Location.List( {} ); // when the data is ready, set the locations property -locations.done(function(){ +locations.done( function() { viewModel.locations = locations; // call start after the AppViewModel is fully initialized route.start(); -}); +} ); ``` ## Why diff --git a/doc/register.md b/doc/register.md index b81e78b..13a7b80 100644 --- a/doc/register.md +++ b/doc/register.md @@ -11,14 +11,14 @@ The following sets `route.data.page = "cart"` when the url is `#cart` and `route.data.page = "home"` when the url is `#`. ```js -route.register("{page}", { page: "home" }); +route.register( "{page}", { page: "home" } ); ``` @param {String} rule the fragment identifier to match. The fragment identifier should contain characters (a-Z), optionally wrapped in braces ( { } ). Identifiers wrapped in braces are interpreted as being properties on can-route’s map. Examples: ```js -route.register("{foo}") -route.register("foo/{bar}") +route.register( "{foo}" ); +route.register( "foo/{bar}" ); ``` @param {Object} [defaults] An object of default values. These defaults are applied to can-route’s map when the route is matched. diff --git a/doc/rule.md b/doc/rule.md index c5daf0f..cc24aa5 100644 --- a/doc/rule.md +++ b/doc/rule.md @@ -6,10 +6,9 @@ @signature `route.rule(url)` ```js -route.register("recipes/{recipeId}"); -route.register("tasks/{taskId}"); - -route.rule("recipes/5") //-> "recipes/{recipeId}" +route.register( "recipes/{recipeId}" ); +route.register( "tasks/{taskId}" ); +route.rule( "recipes/5" ); //-> "recipes/{recipeId}" ``` @param {String} url A url or url fragment. diff --git a/doc/start.md b/doc/start.md index b86ee2b..fbade87 100644 --- a/doc/start.md +++ b/doc/start.md @@ -10,8 +10,7 @@ Sets up the two-way binding between the hash and the can-route observable map and sets the route map to its initial values. ```js -route.register("{page}", { page: "home" })); - +route.register( "{page}", { page: "home" } ); route.start(); route.data.page; // -> "home" ``` @@ -25,7 +24,7 @@ route.data.page; // -> "home" After setting all your routes, call `route.start()`. ```js -route.register("overview/{dateStart}-{dateEnd}"); -route.register("{type}/{id}"); +route.register( "overview/{dateStart}-{dateEnd}" ); +route.register( "{type}/{id}" ); route.start(); ``` diff --git a/doc/stop.md b/doc/stop.md index 1aaf647..bf7c834 100644 --- a/doc/stop.md +++ b/doc/stop.md @@ -9,12 +9,10 @@ Stops listening to the [can-route.data] observable and tears down any setup bind Stops listening to changes in the URL as well as the observable defined in [can-route.data], and removes the current binding. ```js -route.register("{page}", { page: "home" })); - +route.register( "{page}", { page: "home" } ); route.start(); route.data.page = "home"; route.stop(); - route.data.page = "cart"; // hash is still #home ```