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

Commit 9486590

Browse files
committed
refactor(ng:view) Make $route scope agnostic, add $contentLoaded event
Problems: - controller was instantiated immediately on $afterRouteChange (even if no content), that's different compare to ng:controller, which instantiates controllers after compiling - route listened on current scope ($afterRouteChange), so if you were listening on $rootScope ($afterRouteChange), you get called first and current.scope === undefined, which is flaky - route handles scope destroying, but scope is created by ng:view - route fires after/before route change even if there is no route (when no otherwise specified) Solution: - route has no idea about scope, whole scope business moved to ng:view (creating/destroying) - scope is created (and controller instantiated) AFTER compiling the content - that means on $afterRouteChange - there is no scope yet (current.scope === undefined) - added $contentLoaded event fired by ng:view, after linking the content
1 parent e31d1c2 commit 9486590

File tree

4 files changed

+267
-205
lines changed

4 files changed

+267
-205
lines changed

Diff for: src/service/route.js

+5-13
Original file line numberDiff line numberDiff line change
@@ -237,22 +237,16 @@ function $RouteProvider(){
237237

238238
function updateRoute() {
239239
var next = parseRoute(),
240-
last = $route.current,
241-
Controller;
240+
last = $route.current;
242241

243242
if (next && last && next.$route === last.$route
244243
&& equals(next.pathParams, last.pathParams) && !next.reloadOnSearch && !forceReload) {
245-
next.scope = last.scope;
246-
$route.current = next;
247-
copy(next.params, $routeParams);
248-
last.scope && last.scope.$emit('$routeUpdate');
249-
} else {
244+
last.params = next.params;
245+
copy(last.params, $routeParams);
246+
$rootScope.$broadcast('$routeUpdate', last);
247+
} else if (next || last) {
250248
forceReload = false;
251249
$rootScope.$broadcast('$beforeRouteChange', next, last);
252-
if (last && last.scope) {
253-
last.scope.$destroy();
254-
last.scope = null;
255-
}
256250
$route.current = next;
257251
if (next) {
258252
if (next.redirectTo) {
@@ -308,7 +302,5 @@ function $RouteProvider(){
308302
});
309303
return result.join('');
310304
}
311-
312-
313305
}];
314306
}

Diff for: src/widgets.js

+25-14
Original file line numberDiff line numberDiff line change
@@ -544,46 +544,57 @@ var ngViewDirective = ['$http', '$templateCache', '$route', '$anchorScroll', '$c
544544
return {
545545
terminal: true,
546546
link: function(scope, element) {
547-
var changeCounter = 0;
547+
var changeCounter = 0,
548+
lastScope;
548549

549-
processRoute($route.current);
550-
scope.$on('$afterRouteChange', function(event, next) {
550+
scope.$on('$afterRouteChange', function(event, next, previous) {
551551
changeCounter++;
552-
processRoute(next);
553552
});
554553

555554
scope.$watch(function() {return changeCounter;}, function(newChangeCounter) {
556555
var template = $route.current && $route.current.template;
557556

557+
function destroyLastScope() {
558+
if (lastScope) {
559+
lastScope.$destroy();
560+
lastScope = null;
561+
}
562+
}
563+
558564
function clearContent() {
559565
// ignore callback if another route change occured since
560566
if (newChangeCounter == changeCounter) {
561567
element.html('');
562568
}
569+
destroyLastScope();
563570
}
564571

565572
if (template) {
566573
$http.get(template, {cache: $templateCache}).success(function(response) {
567574
// ignore callback if another route change occured since
568575
if (newChangeCounter == changeCounter) {
569576
element.html(response);
570-
$compile(element.contents())($route.current.scope);
577+
destroyLastScope();
578+
579+
var link = $compile(element.contents()),
580+
current = $route.current;
581+
582+
lastScope = current.scope = scope.$new();
583+
if (current.controller) {
584+
$controller(current.controller, {$scope: lastScope});
585+
}
586+
587+
link(lastScope);
588+
lastScope.$emit('$contentLoaded');
589+
590+
// $anchorScroll might listen on event...
571591
$anchorScroll();
572592
}
573593
}).error(clearContent);
574594
} else {
575595
clearContent();
576596
}
577597
});
578-
579-
function processRoute(route) {
580-
if (route) {
581-
route.scope = scope.$new();
582-
if (route.controller) {
583-
$controller(route.controller, {$scope: route.scope});
584-
}
585-
}
586-
}
587598
}
588599
};
589600
}];

0 commit comments

Comments
 (0)