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