You can define two templates: one for "protected" and one for "login":
$stateProvider
.state("root", {
abstract: true,
template: "<ui-view/>"
})
.state("root.protected", {
abstract: true,
template: '<div ui-view="header"></div><div ui-view="container"></div>'
})
.state("root.protected.home", {
url: "/home",
views: {
header: { templateUrl: "/home-header.html" },
container: { templateUrl: "/home-container.html" }
}
})
.state("root.login", {
url: "/login",
templateUrl: "/login.html",
controller: "loginController"
});
You can write whole login html code in login.html. The better solution is to have a state named "unprotected" and define two ui-view for it:
.state("root.unprotected", {
abstract: true,
template: '<div ui-view="header"></div><div ui-view="container"></div>'
})
.state("root.unprotected.login", {
url: "/login",
views: {
header: { templateUrl: "/login-header.html", controller: "loginHeaderController" },
container: { templateUrl: "/login-container.html", controller: "loginContainerController" }
}
});
And also a more better solution is to not define a ui-view for header part of unprotected and have only one ui-view for its container. With this approach you don't need to define header for every unprotected view (if you have any). So you just need to write container template.