In craftkit application, routing is managed by RootViewController, a special type of ViewController.
It defines interface for handling popstate event, by resolveRoutingRequest(route)
method.
When you implement your own RootViewController, you have to implement this method.
The routing request is encapsulated by Route object, and it is passed to the method.
Route object
param | desc |
---|---|
launch | true if called from RootViewController#bringup |
path | parsed path |
event | defined if this is called by browser back/forward with popstate event |
Parsing and normalizing Route.path
is responsibility of your RootViewController implementation. (This is not the same as location.pathname
)
To control History correctly, you have to check popstate event and launch flag like this:
let event = route ? route.event : null;
let launch = route ? route.launch : false;
if( launch ){
// your are in launching sequence, and you should update history
window.history.replaceState({},title,path);
}else{
if( !event ){
// called by browser back/forward with popstate event
window.history.pushState({},title,path);
}
}
This is idiom.
Every time you implement your application's RootViewController, your will write this kind of block.
Example
class Apple extends Craft.UI.View {
template(componentId){
return `
<div class="root">🍎</div>
`;
}
}
class Orange extends Craft.UI.View {
template(componentId){
return `
<div class="root">🍊</div>
`;
}
}
class PageController extends Craft.UI.DefaultRootViewController {
constructor(options){
super(options);
this.data = {
map: {
apple: new Apple(),
orange: new Orange()
}
};
}
resolveRoutingRequest(route){
let path = route.path || 'apple'
let view = this.data.map[path];
this.replaceView(view);
if( route.launch ){
// launching the app
window.history.replaceState({},'','#/'+path);
}else{
if( !route.event ){
// in app navigation
window.history.pushState({},'','#/'+path);
}
}
}
}
This example code can be run on playground like following:
var rootViewController = new PageController();
Craft.Core.Context.setRootViewController(rootViewController);
rootViewController.bringup();
bringup
method starts resolving Route object from popstate.
In this case, default view 🍎 is shown.
Then, focus url bar (command-l), and change trailing 'apple' to 'orange'.
🍊 is shown.
Push back button, 🍎 is shown again.
NOTE
Path normalization is supported by Craft.Core.HashRouter and Craft.Core.PathRouter. This is GoF Strategy pattern.
HashRouter is default. You can set it at the boot time of your application.
// in your bootloader
Craft.Core.Bootstrap.boot({
router : Craft.Core.HashRouter,
didBootApplication : function(){
Craft.Core.Defaults.ALLOW_COMPONENT_SHORTCUT = true;
let rootViewController = new PageController();
Craft.Core.Context.setRootViewController(rootViewController);
rootViewController.bringup();
}
})
// in your RootViewController
let normalized_path = Craft.Core.Context.getRouter().normalize(path);
if( route.launch ){
window.history.replaceState({},'',path);
}else{
if( !route.event ){
window.history.replaceState({},'',path);
}
}
See GitHub for more about boot setting.
Top comments (0)