| OLD | NEW |
| (Empty) | |
| 1 Route |
| 2 ===== |
| 3 |
| 4 Route is a client + server routing library for Dart that helps make building |
| 5 single-page web apps and using `HttpServer` easier. |
| 6 |
| 7 Installation |
| 8 ------------ |
| 9 |
| 10 Add this package to your pubspec.yaml file: |
| 11 |
| 12 dependencies: |
| 13 route_hierarchical: any |
| 14 |
| 15 Then, run `pub install` to download and link in the package. |
| 16 |
| 17 UrlMatcher |
| 18 ---------- |
| 19 Route is built around `UrlMatcher`, an interface that defines URL template |
| 20 parsing, matching and reversing. |
| 21 |
| 22 |
| 23 UrlTemplate |
| 24 ----------- |
| 25 The default implementation of the `UrlMatcher` is `UrlTemplate`. As an example, |
| 26 consider a blog with a home page and an article page. The article URL has the |
| 27 form /article/1234. It can matched by the following template: |
| 28 `/article/:articleId`. |
| 29 |
| 30 Client Routing |
| 31 -------------- |
| 32 |
| 33 Router is a stateful object that contains routes and can perform URL routing |
| 34 on those routes. |
| 35 |
| 36 The `Router` can listen to `Window.onPopState` (or fallback to |
| 37 Window.onHashChange in older browsers) events and invoke the correct |
| 38 handler so that the back button seamlessly works. |
| 39 |
| 40 Example (client.dart): |
| 41 |
| 42 ```dart |
| 43 library client; |
| 44 |
| 45 import 'package:route_hierarchical/client.dart'; |
| 46 |
| 47 main() { |
| 48 var router = new Router(); |
| 49 router.root |
| 50 ..addRoute(name: 'article', path: '/article/:articleId', enter: showArticle) |
| 51 ..addRoute(name: 'home', defaultRoute: true, path: '/', enter: showHome); |
| 52 router.listen(); |
| 53 } |
| 54 |
| 55 void showHome(RouteEvent e) { |
| 56 // nothing to parse from path, since there are no groups |
| 57 } |
| 58 |
| 59 void showArticle(RouteEvent e) { |
| 60 var articleId = e.parameters['articleId']; |
| 61 // show article page with loading indicator |
| 62 // load article from server, then render article |
| 63 } |
| 64 ``` |
| 65 |
| 66 The client side router can let you define nested routes. |
| 67 |
| 68 ```dart |
| 69 var router = new Router(); |
| 70 router.root |
| 71 ..addRoute( |
| 72 name: 'usersList', |
| 73 path: '/users', |
| 74 defaultRoute: true, |
| 75 enter: showUsersList) |
| 76 ..addRoute( |
| 77 name: 'user', |
| 78 path: '/user/:userId', |
| 79 mount: (router) => |
| 80 router |
| 81 ..addDefaultRoute( |
| 82 name: 'articleList', |
| 83 path: '/acticles', |
| 84 enter: showArticlesList) |
| 85 ..addRoute( |
| 86 name: 'article', |
| 87 path: '/article/:articleId', |
| 88 mount: (router) => |
| 89 router |
| 90 ..addDefaultRoute( |
| 91 name: 'view', |
| 92 path: '/view', |
| 93 enter: viewArticle) |
| 94 ..addRoute( |
| 95 name: 'edit', |
| 96 path: '/edit', |
| 97 enter: editArticle))) |
| 98 ``` |
| 99 |
| 100 The mount parameter takes either a function that accepts an instance of a new |
| 101 child router as the only parameter, or an instance of an object that implements |
| 102 Routable interface. |
| 103 |
| 104 ```dart |
| 105 typedef void MountFn(Router router); |
| 106 ``` |
| 107 |
| 108 or |
| 109 |
| 110 ```dart |
| 111 abstract class Routable { |
| 112 void configureRoute(Route router); |
| 113 } |
| 114 ``` |
| 115 |
| 116 In either case, the child router is instantiated by the parent router an |
| 117 injected into the mount point, at which point child router can be configured |
| 118 with new routes. |
| 119 |
| 120 Routing with hierarchical router: when the parent router performs a prefix |
| 121 match on the URL, it removes the matched part from the URL and invokes the |
| 122 child router with the remaining tail. |
| 123 |
| 124 For instance, with the above example lets consider this URL: `/user/jsmith/artic
le/1234`. |
| 125 Route "user" will match `/user/jsmith` and invoke the child router with `/articl
e/1234`. |
| 126 Route "article" will match `/article/1234` and invoke the child router with ``. |
| 127 Route "view" will be matched as the default route. |
| 128 The resulting route path will be: `user -> article -> view`, or simply `user.art
icle.view` |
| 129 |
| 130 Named Routes in Hierarchical Routers |
| 131 ------------------------------------ |
| 132 |
| 133 ```dart |
| 134 router.go('usersList'); |
| 135 router.go('user.articles', {'userId': 'jsmith'}); |
| 136 router.go('user.article.view', { |
| 137 'userId': 'jsmith', |
| 138 'articleId', 1234} |
| 139 ); |
| 140 router.go('user.article.edit', { |
| 141 'userId': 'jsmith', |
| 142 'articleId', 1234} |
| 143 ); |
| 144 ``` |
| 145 |
| 146 If "go" is invoked on child routers, the router can automatically reconstruct |
| 147 and generate the new URL from the state in the parent routers. |
| 148 |
| 149 Server Routing |
| 150 -------------- |
| 151 |
| 152 On the server, route gives you a utility function to match `HttpRequest`s |
| 153 against `UrlPatterns`. |
| 154 |
| 155 ```dart |
| 156 import 'urls.dart'; |
| 157 import 'package:route_hierarchical/server.dart'; |
| 158 import 'package:route_hierarchical/pattern.dart'; |
| 159 |
| 160 HttpServer.bind().then((server) { |
| 161 var router = new Router(server) |
| 162 ..filter(matchesAny(allUrls), authFilter) |
| 163 ..serve(homeUrl).listen(serverHome) |
| 164 ..serve(articleUrl, method: 'GET').listen(serveArticle); |
| 165 }); |
| 166 |
| 167 Future<bool> authFilter(req) { |
| 168 return getUser(getUserIdCookie(req)).then((user) { |
| 169 if (user != null) { |
| 170 return true; |
| 171 } |
| 172 redirectToLoginPage(req); |
| 173 return false; |
| 174 }); |
| 175 } |
| 176 |
| 177 serveArcticle(req) { |
| 178 var articleId = articleUrl.parse(req.path)[0]; |
| 179 // retrieve article data and respond |
| 180 } |
| 181 ``` |
| 182 |
| 183 Further Goals |
| 184 ------------- |
| 185 |
| 186 * Integration with Web UI so that the changing of UI views can happen |
| 187 automatically. |
| 188 * Handling different HTTP methods to help implement REST APIs. |
| 189 * Automatic generation of REST URLs from a single URL pattern, similar to Ruby |
| 190 on Rails |
| 191 * Helpers for nested views and key-value URL schemes common with complex apps. |
| 192 * [Done] ~~Server-side routing for the dart:io v2 HttpServer~~ |
| 193 * [Done] ~~IE 9 support~~ |
| OLD | NEW |