Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 7d69d52

Browse files
matskomhevery
authored andcommitted
chore(ngView): $animate refactoring + transclusion & tests
BREAKING CHANGE: previously ngView only updated its content, after this change ngView will recreate itself every time a new content is included. This ensures that a single rootElement for all the included contents always exists, which makes definition of css styles for animations much easier.
1 parent aa2133a commit 7d69d52

File tree

2 files changed

+207
-183
lines changed

2 files changed

+207
-183
lines changed

src/ngRoute/directive/ngView.js

+73-66
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ ngRouteModule.directive('ngView', ngViewFactory);
1515
* configuration of the `$route` service.
1616
*
1717
* @animations
18-
* enter - happens just after the ngView contents are changed (when the new view DOM element is inserted into the DOM)
19-
* leave - happens just after the current ngView contents change and just before the former contents are removed from the DOM
18+
* enter - animation is used to bring new content into the browser.
19+
* leave - animation is used to animate existing content away.
20+
*
21+
* The enter and leave animation occur concurrently.
2022
*
2123
* @scope
2224
* @example
@@ -30,10 +32,9 @@ ngRouteModule.directive('ngView', ngViewFactory);
3032
<a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
3133
<a href="Book/Scarlet">Scarlet Letter</a><br/>
3234
33-
<div
34-
ng-view
35-
class="example-$animate-container"
36-
ng-$animate="{enter: 'example-enter', leave: 'example-leave'}"></div>
35+
<div class="example-animate-container">
36+
<div ng-view class="view-example"></div>
37+
</div>
3738
<hr />
3839
3940
<pre>$location.path() = {{main.$location.path()}}</pre>
@@ -60,20 +61,13 @@ ngRouteModule.directive('ngView', ngViewFactory);
6061
</file>
6162
6263
<file name="animations.css">
63-
.example-leave, .example-enter {
64+
.view-example {
6465
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
6566
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
6667
-ms-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
6768
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
6869
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
69-
}
70-
71-
.example-$animate-container {
72-
position:relative;
73-
height:100px;
74-
}
7570
76-
.example-$animate-container > * {
7771
display:block;
7872
width:100%;
7973
border-left:1px solid black;
@@ -86,15 +80,20 @@ ngRouteModule.directive('ngView', ngViewFactory);
8680
padding:10px;
8781
}
8882
89-
.example-enter {
83+
.example-animate-container {
84+
position:relative;
85+
height:100px;
86+
}
87+
88+
.view-example.ng-enter {
9089
left:100%;
9190
}
92-
.example-enter.example-enter-active {
91+
.view-example.ng-enter.ng-enter-active {
9392
left:0;
9493
}
9594
96-
.example-leave { }
97-
.example-leave.example-leave-active {
95+
.view-example.ng-leave { }
96+
.view-example.ng-leave.ng-leave-active {
9897
left:-100%;
9998
}
10099
</file>
@@ -164,57 +163,65 @@ function ngViewFactory( $route, $anchorScroll, $compile, $controller,
164163
return {
165164
restrict: 'ECA',
166165
terminal: true,
167-
link: function(scope, element, attr) {
168-
var lastScope,
169-
onloadExp = attr.onload || '';
170-
171-
scope.$on('$routeChangeSuccess', update);
172-
update();
173-
174-
175-
function destroyLastScope() {
176-
if (lastScope) {
177-
lastScope.$destroy();
178-
lastScope = null;
166+
transclude: 'element',
167+
compile: function(element, attr, linker) {
168+
return function(scope, $element, attr) {
169+
var currentScope,
170+
currentElement,
171+
onloadExp = attr.onload || '';
172+
173+
scope.$on('$routeChangeSuccess', update);
174+
update();
175+
176+
function cleanupLastView() {
177+
if (currentScope) {
178+
currentScope.$destroy();
179+
currentScope = null;
180+
}
181+
if(currentElement) {
182+
$animate.leave(currentElement);
183+
currentElement = null;
184+
}
179185
}
180-
}
181-
182-
function clearContent() {
183-
$animate.leave(element.contents());
184-
destroyLastScope();
185-
}
186186

187-
function update() {
188-
var locals = $route.current && $route.current.locals,
189-
template = locals && locals.$template;
190-
191-
if (template) {
192-
clearContent();
193-
var enterElements = jqLite('<div></div>').html(template).contents();
194-
$animate.enter(enterElements, element);
195-
196-
var link = $compile(enterElements),
197-
current = $route.current,
198-
controller;
199-
200-
lastScope = current.scope = scope.$new();
201-
if (current.controller) {
202-
locals.$scope = lastScope;
203-
controller = $controller(current.controller, locals);
204-
if (current.controllerAs) {
205-
lastScope[current.controllerAs] = controller;
206-
}
207-
element.children().data('$ngControllerController', controller);
187+
function update() {
188+
var locals = $route.current && $route.current.locals,
189+
template = locals && locals.$template;
190+
191+
if (template) {
192+
var newScope = scope.$new();
193+
linker(newScope, function(clone) {
194+
cleanupLastView();
195+
196+
clone.html(template);
197+
$animate.enter(clone, null, $element);
198+
199+
var link = $compile(clone.contents()),
200+
current = $route.current;
201+
202+
currentScope = current.scope = newScope;
203+
currentElement = clone;
204+
205+
if (current.controller) {
206+
locals.$scope = currentScope;
207+
var controller = $controller(current.controller, locals);
208+
if (current.controllerAs) {
209+
currentScope[current.controllerAs] = controller;
210+
}
211+
clone.data('$ngControllerController', controller);
212+
clone.contents().data('$ngControllerController', controller);
213+
}
214+
215+
link(currentScope);
216+
currentScope.$emit('$viewContentLoaded');
217+
currentScope.$eval(onloadExp);
218+
219+
// $anchorScroll might listen on event...
220+
$anchorScroll();
221+
});
222+
} else {
223+
cleanupLastView();
208224
}
209-
210-
link(lastScope);
211-
lastScope.$emit('$viewContentLoaded');
212-
lastScope.$eval(onloadExp);
213-
214-
// $anchorScroll might listen on event...
215-
$anchorScroll();
216-
} else {
217-
clearContent();
218225
}
219226
}
220227
}

0 commit comments

Comments
 (0)