I would say, that a significant confusion could come from the fact, that our super root state 'myapp'
uses template named index.html
.
I would suggest to change that naming and this adjusted example then should work. The index.html, will be used only as a starting page (referencing angular, UI-Router...)
<!DOCTYPE html>
<html ng-app="MyApp" ng-strict-di>
<head>
<title>my app</title>
<script src="angular.js"></script>
<script src="angular-ui-router.js"></script>
<script ...
</head>
<body>
// place for our root state
<div ui-view=""></div>
</body>
</html>
Now, we can target this ui-view 3 ways. We can use implicit, or explicti relative or explicit aboslute naming build as viewName@stateName
. These three defintions are the same:
// I. no views : {} needed, we target parent unnamed
.state('myapp', {
abstract: true,
templateUrl: 'tpl.myapp.html'
})
// II. we target explicit parent unnamed view - relative notation
.state('myapp', {
abstract: true,
views : {
'': {
templateUrl: 'tpl.myapp.html'
}
}
})
// III. we target explicit parent unnamed view - absolute notation
.state('myapp', {
abstract: true,
views : {
'@': { // before @ is view name, after @ is state name, empty for root
templateUrl: 'tpl.myapp.html'
}
}
})
As we can se,, for the 'myapp' state we used different templateUrl: 'tpl.myapp.html'
. Its content is different the index.html, it could be:
<div>
<h2>the root myapp template</h2>
place for child states:
<div ui-view="main"></div>
</div>
And now we have to target this view only explicit way (but could be relative or absolute:
.state('myapp.home', {
url: "/",
views: {
// could be "main@myapp" as well
"main": {
controller: 'HomeCtrl',
templateUrl: 'includes/home.html'
}
}
})
Check the example here
Read more about it here: