| OLD | NEW |
| 1 part of angular.routing; | 1 part of angular.routing; |
| 2 | 2 |
| 3 /** | 3 /** |
| 4 * A directive that works with the [Router] and loads the template associated | 4 * A directive that works with the [Router] and loads the template associated |
| 5 * with the current route. | 5 * with the current route. |
| 6 * | 6 * |
| 7 * <ng-view></ng-view> | 7 * <ng-view></ng-view> |
| 8 * | 8 * |
| 9 * [NgViewDirective] can work with [NgViewDirective] to define nested views | 9 * [NgViewDirective] can work with [NgViewDirective] to define nested views |
| 10 * for hierarchical routes. For example: | 10 * for hierarchical routes. For example: |
| 11 * | 11 * |
| 12 * void initRoutes(Router router, RouteViewFactory view) { | 12 * void initRoutes(Router router, ViewFactory view) { |
| 13 * router.root | 13 * router.root |
| 14 * ..addRoute( | 14 * ..addRoute( |
| 15 * name: 'library', | 15 * name: 'library', |
| 16 * path: '/library', | 16 * path: '/library', |
| 17 * enter: view('library.html'), | 17 * enter: view('library.html'), |
| 18 * mount: (Route route) => route | 18 * mount: (Route route) => route |
| 19 * ..addRoute( | 19 * ..addRoute( |
| 20 * name: 'all', | 20 * name: 'all', |
| 21 * path: '/all', | 21 * path: '/all', |
| 22 * enter: view('book_list.html')) | 22 * enter: view('book_list.html')) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 48 * <ng-view></ng-view> | 48 * <ng-view></ng-view> |
| 49 * </div> | 49 * </div> |
| 50 * | 50 * |
| 51 * book_list.html: | 51 * book_list.html: |
| 52 * | 52 * |
| 53 * <ul> | 53 * <ul> |
| 54 * <li><a href="/library/12345/overview">Book 12345</a> | 54 * <li><a href="/library/12345/overview">Book 12345</a> |
| 55 * <li><a href="/library/23456/overview">Book 23456</a> | 55 * <li><a href="/library/23456/overview">Book 23456</a> |
| 56 * </ul> | 56 * </ul> |
| 57 */ | 57 */ |
| 58 @Decorator( | 58 @NgDirective( |
| 59 selector: 'ng-view', | 59 selector: 'ng-view', |
| 60 module: NgView.module, | 60 publishTypes: const [RouteProvider], |
| 61 children: Directive.TRANSCLUDE_CHILDREN) | 61 visibility: NgDirective.CHILDREN_VISIBILITY) |
| 62 class NgView implements DetachAware, RouteProvider { | 62 class NgViewDirective implements NgDetachAware, RouteProvider { |
| 63 static final Module _module = new Module() | 63 final NgRoutingHelper locationService; |
| 64 ..factory(RouteProvider, (i) => i.get(NgView)); | 64 final BlockCache blockCache; |
| 65 | 65 final Injector injector; |
| 66 static module() => _module; | 66 final Element element; |
| 67 | 67 final Scope scope; |
| 68 final NgRoutingHelper _locationService; | |
| 69 final ViewCache _viewCache; | |
| 70 final Injector _injector; | |
| 71 final Scope _scope; | |
| 72 RouteHandle _route; | 68 RouteHandle _route; |
| 73 | 69 |
| 74 final ViewPort _viewPort; | 70 Block _previousBlock; |
| 75 | 71 Scope _previousScope; |
| 76 View _view; | |
| 77 Scope _childScope; | |
| 78 Route _viewRoute; | 72 Route _viewRoute; |
| 79 | 73 |
| 80 | 74 NgViewDirective(this.element, this.blockCache, |
| 81 NgView(this._viewCache, Injector injector, Router router, | 75 Injector injector, Router router, |
| 82 this._scope, this._viewPort) | 76 this.scope) |
| 83 : _injector = injector, | 77 : injector = injector, |
| 84 _locationService = injector.get(NgRoutingHelper) | 78 locationService = injector.get(NgRoutingHelper) |
| 85 { | 79 { |
| 86 RouteProvider routeProvider = _injector.parent.get(NgView); | 80 RouteProvider routeProvider = injector.parent.get(NgViewDirective); |
| 87 _route = routeProvider != null ? | 81 _route = routeProvider != null ? |
| 88 routeProvider.route.newHandle() : | 82 routeProvider.route.newHandle() : |
| 89 router.root.newHandle(); | 83 router.root.newHandle(); |
| 90 _locationService._registerPortal(this); | 84 locationService._registerPortal(this); |
| 91 _maybeReloadViews(); | 85 _maybeReloadViews(); |
| 92 } | 86 } |
| 93 | 87 |
| 94 void _maybeReloadViews() { | 88 void _maybeReloadViews() { |
| 95 if (_route.isActive) _locationService._reloadViews(startingFrom: _route); | 89 if (_route.isActive) locationService._reloadViews(startingFrom: _route); |
| 96 } | 90 } |
| 97 | 91 |
| 98 void detach() { | 92 detach() { |
| 99 _route.discard(); | 93 _route.discard(); |
| 100 _locationService._unregisterPortal(this); | 94 locationService._unregisterPortal(this); |
| 101 } | 95 } |
| 102 | 96 |
| 103 void _show(_View viewDef, Route route, List<Module> modules) { | 97 _show(String templateUrl, Route route, List<Module> modules) { |
| 104 assert(route.isActive); | 98 assert(route.isActive); |
| 105 | 99 |
| 106 if (_viewRoute != null) return; | 100 if (_viewRoute != null) return; |
| 107 _viewRoute = route; | 101 _viewRoute = route; |
| 108 | 102 |
| 109 StreamSubscription _leaveSubscription; | 103 StreamSubscription _leaveSubscription; |
| 110 _leaveSubscription = route.onLeave.listen((_) { | 104 _leaveSubscription = route.onLeave.listen((_) { |
| 111 _leaveSubscription.cancel(); | 105 _leaveSubscription.cancel(); |
| 112 _leaveSubscription = null; | 106 _leaveSubscription = null; |
| 113 _viewRoute = null; | 107 _viewRoute = null; |
| 114 _cleanUp(); | 108 _cleanUp(); |
| 115 }); | 109 }); |
| 116 | 110 |
| 117 var viewInjector = modules == null ? | 111 var viewInjector = injector; |
| 118 _injector : | 112 if (modules != null) { |
| 119 forceNewDirectivesAndFilters(_injector, modules); | 113 viewInjector = forceNewDirectivesAndFilters(viewInjector, modules); |
| 114 } |
| 120 | 115 |
| 121 var newDirectives = viewInjector.get(DirectiveMap); | 116 var newDirectives = viewInjector.get(DirectiveMap); |
| 122 var viewFuture = viewDef.templateHtml != null ? | 117 blockCache.fromUrl(templateUrl, newDirectives).then((blockFactory) { |
| 123 new Future.value(_viewCache.fromHtml(viewDef.templateHtml, newDirectives
)) : | 118 _cleanUp(); |
| 124 _viewCache.fromUrl(viewDef.template, newDirectives); | 119 _previousScope = scope.createChild(new PrototypeMap(scope.context)); |
| 120 _previousBlock = blockFactory( |
| 121 viewInjector.createChild( |
| 122 [new Module()..value(Scope, _previousScope)])); |
| 125 | 123 |
| 126 viewFuture.then((viewFactory) { | 124 _previousBlock.elements.forEach((elm) => element.append(elm)); |
| 127 _cleanUp(); | |
| 128 _childScope = _scope.createChild(new PrototypeMap(_scope.context)); | |
| 129 _view = viewFactory( | |
| 130 viewInjector.createChild([new Module()..value(Scope, _childScope)])); | |
| 131 | |
| 132 var view = _view; | |
| 133 _scope.rootScope.domWrite(() { | |
| 134 _viewPort.insert(view); | |
| 135 }); | |
| 136 }); | 125 }); |
| 137 } | 126 } |
| 138 | 127 |
| 139 void _cleanUp() { | 128 _cleanUp() { |
| 140 if (_view == null) return; | 129 if (_previousBlock == null) return; |
| 141 | 130 |
| 142 var view = _view; | 131 _previousBlock.remove(); |
| 143 var childScope = _childScope; | 132 _previousScope.destroy(); |
| 144 _scope.rootScope.domWrite(() { | |
| 145 _viewPort.remove(view); | |
| 146 childScope.destroy(); | |
| 147 }); | |
| 148 | 133 |
| 149 _view = null; | 134 _previousBlock = null; |
| 150 _childScope = null; | 135 _previousScope = null; |
| 151 } | 136 } |
| 152 | 137 |
| 153 Route get route => _viewRoute; | 138 Route get route => _viewRoute; |
| 154 | |
| 155 String get routeName => _viewRoute.name; | 139 String get routeName => _viewRoute.name; |
| 156 | |
| 157 Map<String, String> get parameters { | 140 Map<String, String> get parameters { |
| 158 var res = <String, String>{}; | 141 var res = <String, String>{}; |
| 159 var route = _viewRoute; | 142 var p = _viewRoute; |
| 160 while (route != null) { | 143 while (p != null) { |
| 161 res.addAll(route.parameters); | 144 res.addAll(p.parameters); |
| 162 route = route.parent; | 145 p = p.parent; |
| 163 } | 146 } |
| 164 return res; | 147 return res; |
| 165 } | 148 } |
| 166 } | 149 } |
| 167 | 150 |
| 168 | 151 |
| 169 /** | 152 /** |
| 170 * Class that can be injected to retrieve information about the current route. | 153 * Class that can be injected to retrieve information about the current route. |
| 171 * For example: | 154 * For example: |
| 172 * | 155 * |
| 173 * @Component(/* ... */) | 156 * @NgComponent(/* ... */) |
| 174 * class MyComponent implement DetachAware { | 157 * class MyComponent implement NgDetachAware { |
| 175 * RouteHandle route; | 158 * RouteHandle route; |
| 176 * | 159 * |
| 177 * MyComponent(RouteProvider routeProvider) { | 160 * MyComponent(RouteProvider routeProvider) { |
| 178 * _loadFoo(routeProvider.parameters['fooId']); | 161 * _loadFoo(routeProvider.parameters['fooId']); |
| 179 * route = routeProvider.route.newHandle(); | 162 * route = routeProvider.route.newHandle(); |
| 180 * route.onEnter.listen((RouteEvent e) { | 163 * route.onRoute.listen((RouteEvent e) { |
| 181 * // Do something when the route is activated. | 164 * // Do something when the route is activated. |
| 182 * }); | 165 * }); |
| 183 * route.onLeave.listen((RouteEvent e) { | 166 * route.onLeave.listen((RouteEvent e) { |
| 184 * // Do something when the route is de-activated. | 167 * // Do something when the route is diactivated. |
| 185 * e.allowLeave(allDataSaved()); | 168 * e.allowLeave(allDataSaved()); |
| 186 * }); | 169 * }); |
| 187 * } | 170 * } |
| 188 * | 171 * |
| 189 * detach() { | 172 * detach() { |
| 190 * // The route handle must be discarded. | 173 * // The route handle must be discarded. |
| 191 * route.discard(); | 174 * route.discard(); |
| 192 * } | 175 * } |
| 193 * | 176 * |
| 194 * Future<bool> allDataSaved() { | 177 * Future<bool> allDataSaved() { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 209 /** | 192 /** |
| 210 * Returns the name of the current route. | 193 * Returns the name of the current route. |
| 211 */ | 194 */ |
| 212 String get routeName; | 195 String get routeName; |
| 213 | 196 |
| 214 /** | 197 /** |
| 215 * Returns parameters for this route. | 198 * Returns parameters for this route. |
| 216 */ | 199 */ |
| 217 Map<String, String> get parameters; | 200 Map<String, String> get parameters; |
| 218 } | 201 } |
| OLD | NEW |