Tonight, I try to figure out push state in Dart. Any client-side MVC framework worth its salt needs push state routing and, dammit, Hipster MVC is worth salt.
So I start with an empty page that loads in a Dart script:
<html> <head> <title>Hipster Push State</title> <script type="application/dart" src="main.dart"></script> <script type="text/javascript"> // start Dart navigator.webkitStartDart(); </script> </head> <body> <h1>Push that state!</h1> </body> </html>In that
main.dart
entry point, I define render()
and template()
functions:render(num) { var el = document.query('body'); el.innerHTML = template(num); } template(num) { return """ <h1>$num</h1> <p>Now we're on page <b>$num</b>.</p>"""; }The
render()
function draws the result of the template in the page so that render('One');
results in:Next, I define a method that will navigate to a particular page after a given number of seconds:
navAfter(page_number, delay) { window.setTimeout(() { render(page_number); }, delay * 1000); }If I then define
main()
to be:main() { navAfter('One', 1); navAfter('Two', 2); navAfter('Three', 3); }Then, I see page "One", page "Two" and finally page "Three". But the URL remains the same throughout and, if I click back, then I leave this sample app entirely.
So, instead of rendering the page when I nav-after, I route to the correct page:
navAfter(page_number, delay) { window.setTimeout(() { route(page_number); }, delay * 1000); }This route function then renders the appropriate HTML snippet, but it is also responsible for pushing the current state into History:
route(num) { window.history.pushState(null, num, window.location.pathname + "#$num"); render(num); }With that, I have three different pages in history, but, when I click back to page "Two", I still see page three rendered:
To fix that, I need to start a history listener at the end of my
main()
entry point:main() { navAfter('One', 1); navAfter('Two', 2); navAfter('Three', 3); startHistory(); }That history listener is responsible for listening to the window's popState events:
startHistory() { window. on. popState. add((event) { var page_num = window.location.hash.replaceFirst('#', ''); print(page_num); render(page_num); }); }With that, I have the proper page displaying for the current route:
This is not quite ready to be popped into Hipster MVC, but it was a nice way to ease into it.
Day #316
No comments:
Post a Comment