I can't seem to reproduce this on jsFiddle (mhevery says it's because you need real async with delay to reproduce, but the only way I know to include templates for ngInclude in jsFiddle are inline script tags), but here's how to set it up with two local files:
<html>
<head>
<script src="http://docs.angularjs.org/angular-1.0.1.min.js"></script>
<script type="text/javascript">
angular.module('myApp', [], function($routeProvider) {
$routeProvider.when('/topic', {
controller: TopicsCtrl,
template: 'Controller: {{name}}'
});
$routeProvider.when('/topic/:topicId', {
controller: TopicCtrl,
template: 'Controller: {{name}}<br />Topic ID: {{params.topicId}}'
});
$routeProvider.otherwise({redirectTo: '/topic'});
});
function TopicsCtrl($scope) {
$scope.name = 'TopicsCtrl';
};
function TopicCtrl($scope) {
$scope.name = 'TopicCtrl';
$scope.params = $routeParams;
};
</script>
</head>
<body ng-app="myApp">
<div ng-include src="'app.html'"></div>
</body>
</html>
<a href="#/topic">All topics</a>
<a href="#/topic/1">Topic 1</a>
<a href="#/topic/2">Topic 2</a>
<a href="#/topic/3">Topic 3</a>
<hr />
<div ng-view></div>
Page loads, redirects to #/topic, and shows 'Controller: TopicCtrl' in the view.
Page loads, does not redirect. If you click any link, the proper view is loaded. However, if you then reload, the view will not be properly loaded.
If you move the ng-view into index.html it works fine.
Mi拧ko writes:
if ng-view instantiation is delayed (through ng-include) then the $route instantiation is delayed as well. This means that $route will miss the location change event.
Fix:
Run $route update function on instantiation (not just on the location change event)
After a bunch of false starts, here's how I did it (using the proposed fix):
If this is my app definition:
var myApp = angular.module( ... );
This is where I update the $route update function:
myApp.run(['$route', function($route) {
$route.reload();
}]);
Now ng-view can be reliably nested inside ng-include.
myApp.run() is the place for application initialization: http://docs.angularjs.org/api/angular.Module
+1
Thanks for the fix.
As part of our effort to clean out old issues, this issue is being automatically closed since it has been inactivite for over two months.
Please try the newest versions of Angular (1.0.8 and 1.2.0-rc.1), and if the issue persists, comment below so we can discuss it.
Thanks!
This issue still exists, but saidimu's fix still works. You don't have to call $route.reload() though, including it as a dependency to a run function is enough. I wound up with this:
myApp.run(['$route', angular.noop]);
This is still an issue in 1.2.0-rc.3
The workarounds mentioned above work but if you inject $route into a run block all unit tests depending on the main module and using $scope.apply() fails (the app is doing $http calls to get the template when the route reloads or something). Don't know if that is a separate issue or not but certainly related to the workaround.
Bump..
this issue is still there, it is call controller twice when I inject $route to app.run. Why?
does anyone know if this annoying bug will be fixed in 1.3 ?
hello I am trying to load a template located on a seperate file, but when I look at the console, the template doesnt load up. Can someone help me here?
Thanks
I just checked it locally, and this still happens in the latest snapshot. Reopen.
I am also experiencing this issue (in 1.2.18), but haven't seen it in other projects where I'm using a different (I think older) version - is it fixed in some versions?
Had to add $route.reload() again with 1.3.0-beta.17
Still happen on rc.0
So, we tried this a while ago --- the thing is it was reverted: 308598795af75c33a966ecb3124f4a640d72458d
Basically the issue is, ngView will instantiate a route, but won't update immediately --- the ngView's template content is empty until the route updates with a template.
It does work if the route update happens, however (http://plnkr.co/edit/MoqyggpCnCoSAAq97359?p=preview)
So, the reason this fix was reverted was, it means we end up emitting events which were maybe not expected to be emitted, or something. I don't have the details on the specific failures that caused the revert, but we might be able to re-land it, because that's essentially the only thing that breaks this.
_edit_
This pull request broke some of our code due to a change in the ordering of the onLocationSuccess event and the route resolve logic. In the past, onLocationSuccess was always fired before the route's resolve method was called. As of this change, onLocationSuccess fired after the resolve method when navigating to a new page (though no change was observed on initial page load).
ng 1.3.8, reload fix worked for me :)
I believe this is also requiring me to do some silly stuff in my unit tests as a workaround:
This bug still exists in 1.3.15
by adding the following code it's fixed
app.run(['$route', function($route) {
$route.reload();
}]);
The bug still exists in 1.4.1 as well. We have deeply nested ng-include that has a 'page' directive which contains ng-view in the template.
It seems just the act of injecting $route into the run block does the trick for us. Someone else pointed that out earlier in thread, "tobyn commented on Sep 6, 2013" but the noop isn't necessary just the injection.
// doesn't work!
app.run(['$log', '$rootScope', function ($log, $rootScope) {
// nothing
}
// works!
app.run(['$log', '$rootScope', '$route', function ($log, $rootScope, $route) {
// nothing
}
+1 to blackbeltdev's comment.
There's an interesting sentence in here which might explain why injecting the $route fixes the problem with ng-include.
"Instead, I have another, optional, sub-controller which does nothing but inject the $route service (which forces AngularJS to call the $routeProvider)."
1.5.0 has the same behavior. Requires you to inject $route into run(..)
The fix was reverted in https://github.com/angular/angular.js/commit/75bf80700e992e6d60f16f6360d400ad28049d36
Then I suppose the issue should be re-opened.
It will be re-applied for
v1.6.x, with a breaking change notice and possibly a way to disable
the feature is tests.
We just have to make sure the BC notice is added to the CL when the time comes.
+1 to blackbeltdev's comment. =) Works for 1.5.x
this is still not fixed in 1.5.8
@HaroldStruwig, this was fixed on master with #14893 (and will be included in the upcoming v1.6.0 release. The fix can't be backported as-is, due to a slight breaking change.
Although we could backport it, but change the default to to non-eager $route instantiation (to avoid the breaking change), it isn't worth it. Manually fixing this is easier than opting-into eager-instantiation. E.g.:
// IF we had backported the fix (which we won't)
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.eagerInstantiationEnabled(true);
}]);
// vs
// Manually fixing it in v1.5.x (much sorter and recommended)
app.run(['$route', angular.noop]);
The work-around/fix for v1.5.x is even document here.