| OLD | NEW |
| 1 /** | 1 /** |
| 2 * The [routing] library makes it easier to build large single-page | 2 * The [routing] library makes it easier to build large single-page applications
. The |
| 3 * applications. The library lets you map the browser address bar to semantic | 3 * library lets you map the browser address bar to semantic structure of your |
| 4 * structure of your application and keeps them in sync. | 4 * application and keeps them in sync. |
| 5 * | 5 * |
| 6 * Angular uses the [route_hierarchical] package to define application routes | 6 * Angular uses the [route_hierarchical] package to define application routes an
d |
| 7 * and to provide custom tools to make it easier to use routing with Angular | 7 * to provide custom tools to make it easier to use routing with Angular templat
es. |
| 8 * templates. | |
| 9 * | 8 * |
| 10 * Lets consider a simple recipe book application. The application might have | 9 * Lets consider a simple recipe book application. The application might have |
| 11 * the following pages: | 10 * the following pages: |
| 12 * | 11 * |
| 13 * * recipes list/search | 12 * * recipes list/search |
| 14 * * add new recipe | 13 * * add new recipe |
| 15 * * view recipe | 14 * * view recipe |
| 16 * * edit recipe | 15 * * edit recipe |
| 17 * | 16 * |
| 18 * Each of those pages can be represented by an address: | 17 * Each of those pages can be represented by an address: |
| 19 * | 18 * |
| 20 * * `/recipes` | 19 * * `/recipes` |
| 21 * * `/addRecipe` | 20 * * `/addRecipe` |
| 22 * * `/recipe/:recipeId/view` | 21 * * `/recipe/:recipeId/view` |
| 23 * * `/recipe/:recipeId/edit` | 22 * * `/recipe/:recipeId/edit` |
| 24 * | 23 * |
| 25 * | 24 * |
| 26 * Lets try to define those routes in Angular. To get started we need to | 25 * Lets try to define those routes in Angular. To get started we need to |
| 27 * provide an implementation of [RouteInitializerFn] function. | 26 * provide an implementation of [RouteInitializer] interface. |
| 28 * | 27 * |
| 29 * void initRoutes(Router router, ViewFactory view) { | 28 * class RecipesRouteInitializer implements RouteInitializer { |
| 30 * // define routes here. | 29 * void init(Router router, ViewFactory view) { |
| 31 * } | 30 * // define routes here. |
| 31 * } |
| 32 * } |
| 32 * | 33 * |
| 33 * var module = new Module() | 34 * var module = new Module() |
| 34 * ..factory(RouteInitializerFn, (_) => initRoutes); | 35 * ..type(RouteInitializer, implementedBy: RecipesRouteInitializer); |
| 35 * | 36 * |
| 36 * Lets see how we could define our routes using the routing framework: | 37 * Lets see how we could define our routes using the routing framework: |
| 37 * | 38 * |
| 38 * void initRoutes(Router router, ViewFactory view) { | 39 * class RecipesRouteInitializer implements RouteInitializer { |
| 39 * router | 40 * void init(Router router, ViewFactory view) { |
| 40 * ..addRoute( | 41 * router |
| 41 * name: 'recipes', | 42 * ..addRoute( |
| 42 * path: '/recipes', | 43 * name: 'recipes', |
| 43 * enter: view('recipes.html')) | 44 * path: '/recipes', |
| 44 * ..addRoute( | 45 * enter: view('recipes.html')) |
| 45 * name: 'addRecipe', | 46 * ..addRoute( |
| 46 * path: '/addRecipe', | 47 * name: 'addRecipe', |
| 47 * enter: view('addRecipe.html')) | 48 * path: '/addRecipe', |
| 48 * ..addRoute( | 49 * enter: view('addRecipe.html')) |
| 49 * name: 'viewRecipe', | 50 * ..addRoute( |
| 50 * path: '/recipe/:recipeId/view', | 51 * name: 'viewRecipe', |
| 51 * enter: view('viewRecipe.html')) | 52 * path: '/recipe/:recipeId/view', |
| 52 * ..addRoute( | 53 * enter: view('viewRecipe.html')) |
| 53 * name: 'editRecipe', | 54 * ..addRoute( |
| 54 * path: '/recipe/:recipeId/edit', | 55 * name: 'editRecipe', |
| 55 * enter: view('editRecipe.html')); | 56 * path: '/recipe/:recipeId/edit', |
| 57 * enter: view('editRecipe.html')); |
| 58 * } |
| 56 * } | 59 * } |
| 57 * | 60 * |
| 58 * We defined 4 routes and for each route we set views (templates) to be | 61 * We defined 4 routes and for each route we set views (templates) to be |
| 59 * displayed when that route is "entered". For example, when the browser URL | 62 * displayed when that route is "entered". For example, when the browser URL |
| 60 * is set to `/recipes`, the `recipes.html` will be displayed. | 63 * is set to `/recipes`, the `recipes.html` will be displayed. |
| 61 * | 64 * |
| 62 * You have to tell Angular where to load views by putting `<ng-view>` tag in | 65 * You have to tell Angular where to load views by putting `<ng-view>` tag in |
| 63 * you template. | 66 * you template. |
| 64 * | 67 * |
| 65 * Notice that `viewRecipe` and `editRecipe` route paths have `recipeId` | 68 * Notice that `viewRecipe` and `editRecipe` route paths have `recipeId` |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 * easier. For example, notice that we didn't need to manually call | 117 * easier. For example, notice that we didn't need to manually call |
| 115 * [StreamSubscription.cancel] for subscription to [Route.onLeave]. Calling | 118 * [StreamSubscription.cancel] for subscription to [Route.onLeave]. Calling |
| 116 * [RouteHandle.discard] unsubscribes all listeneters created for the handle. | 119 * [RouteHandle.discard] unsubscribes all listeneters created for the handle. |
| 117 * | 120 * |
| 118 * | 121 * |
| 119 * # Hierarchical Routes | 122 * # Hierarchical Routes |
| 120 * | 123 * |
| 121 * The routing framework allows us to define trees of routes. In our recipes | 124 * The routing framework allows us to define trees of routes. In our recipes |
| 122 * example we could have defined our routes like this: | 125 * example we could have defined our routes like this: |
| 123 * | 126 * |
| 124 * void initRoutes(Router router, ViewFactory view) { | 127 * class RecipesRouteInitializer implements RouteInitializer { |
| 125 * router | 128 * void init(Router router, ViewFactory view) { |
| 126 * ..addRoute( | 129 * router |
| 127 * name: 'recipes', | 130 * ..addRoute( |
| 128 * path: '/recipes', | 131 * name: 'recipes', |
| 129 * enter: view('recipes.html')) | 132 * path: '/recipes', |
| 130 * ..addRoute( | 133 * enter: view('recipes.html')) |
| 131 * name: 'addRecipe', | 134 * ..addRoute( |
| 132 * path: '/addRecipe', | 135 * name: 'addRecipe', |
| 133 * enter: view('addRecipe.html')) | 136 * path: '/addRecipe', |
| 134 * ..addRoute( | 137 * enter: view('addRecipe.html')) |
| 135 * name: 'recipe', | 138 * ..addRoute( |
| 136 * path: '/recipe/:recipeId', | 139 * name: 'recipe', |
| 137 * mount: (Route route) => route | 140 * path: '/recipe/:recipeId', |
| 138 * ..addRoute( | 141 * mount: (Route route) => route |
| 139 * name: 'view', | 142 * ..addRoute( |
| 140 * path: '/view', | 143 * name: 'view', |
| 141 * enter: view('viewRecipe.html')) | 144 * path: '/view', |
| 142 * ..addRoute( | 145 * enter: view('viewRecipe.html')) |
| 143 * name: 'edit', | 146 * ..addRoute( |
| 144 * path: '/edit', | 147 * name: 'edit', |
| 145 * enter: view('editRecipe.html'))); | 148 * path: '/edit', |
| 149 * enter: view('editRecipe.html'))); |
| 150 * } |
| 146 * } | 151 * } |
| 147 * } | |
| 148 */ | 152 */ |
| 149 library angular.routing; | 153 library angular.routing; |
| 150 | 154 |
| 151 import 'dart:async'; | 155 import 'dart:async'; |
| 152 import 'dart:html'; | 156 import 'dart:html'; |
| 153 | 157 |
| 154 import 'package:di/di.dart'; | 158 import 'package:di/di.dart'; |
| 155 import 'package:angular/angular.dart'; | 159 import 'package:angular/angular.dart'; |
| 156 import 'package:route_hierarchical/client.dart'; | 160 import 'package:route_hierarchical/client.dart'; |
| 157 export 'package:route_hierarchical/client.dart'; | 161 export 'package:route_hierarchical/client.dart'; |
| 158 | 162 |
| 159 part 'routing.dart'; | 163 part 'routing.dart'; |
| 160 part 'ng_view.dart'; | 164 part 'ng_view.dart'; |
| 161 part 'ng_bind_route.dart'; | 165 part 'ng_bind_route.dart'; |
| 162 | 166 |
| 163 class NgRoutingModule extends Module { | 167 class NgRoutingModule extends Module { |
| 164 NgRoutingModule({bool usePushState: true}) { | 168 NgRoutingModule({bool usePushState: true}) { |
| 165 type(NgRoutingUsePushState); | 169 type(NgRoutingUsePushState); |
| 166 factory(Router, (injector) { | 170 factory(Router, (injector) { |
| 167 var useFragment = !injector.get(NgRoutingUsePushState).usePushState; | 171 var useFragment = !injector.get(NgRoutingUsePushState).usePushState; |
| 168 return new Router(useFragment: useFragment, | 172 return new Router(useFragment: useFragment, |
| 169 windowImpl: injector.get(Window)); | 173 windowImpl: injector.get(Window)); |
| 170 }); | 174 }); |
| 171 type(NgRoutingHelper); | 175 type(NgRoutingHelper); |
| 172 value(RouteProvider, null); | 176 value(RouteProvider, null); |
| 173 value(RouteInitializer, null); | 177 value(RouteInitializer, null); |
| 174 value(RouteInitializerFn, null); | |
| 175 | 178 |
| 176 // directives | 179 // directives |
| 177 value(NgViewDirective, null); | 180 value(NgViewDirective, null); |
| 178 type(NgBindRouteDirective); | 181 type(NgBindRouteDirective); |
| 179 } | 182 } |
| 180 } | 183 } |
| 181 | 184 |
| 182 /** | 185 /** |
| 183 * Allows configuration of [Router.useFragment]. By default [usePushState] is | 186 * Allows configuration of [Router.useFragment]. By default [usePushState] is |
| 184 * true, so the router will listen to [Window.onPopState] and route URLs like | 187 * true, so the router will listen to [Window.onPopState] and route URLs like |
| 185 * "http://host:port/foo/bar?baz=qux". Both the path and query parts of the URL | 188 * "http://host:port/foo/bar?baz=qux". Both the path and query parts of the URL |
| 186 * are used by the router. If [usePushState] is false, router will listen to | 189 * are used by the router. If [usePushState] is false, router will listen to |
| 187 * [Window.onHashChange] and route URLs like | 190 * [Window.onHashChange] and route URLs like |
| 188 * "http://host:port/path#/foo/bar?baz=qux". Everything after hash (#) is used | 191 * "http://host:port/path#/foo/bar?baz=qux". Everything after hash (#) is used |
| 189 * by the router. | 192 * by the router. |
| 190 */ | 193 */ |
| 191 @NgInjectableService() | 194 @NgInjectableService() |
| 192 class NgRoutingUsePushState { | 195 class NgRoutingUsePushState { |
| 193 final bool usePushState; | 196 final bool usePushState; |
| 194 NgRoutingUsePushState(): usePushState = true; | 197 NgRoutingUsePushState(): usePushState = true; |
| 195 NgRoutingUsePushState.value(this.usePushState); | 198 NgRoutingUsePushState.value(this.usePushState); |
| 196 } | 199 } |
| OLD | NEW |