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 |