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