Sorry if this is a stupid question I am still fairly new to this. I have a basic understanding of how the navigation works with angular js but I cant figure out how to set a starting page. I want to set my login page as my start page the url shows that the login page is open ("http://localhost:8100/#/template/login") but it only displays a blank header which I suspect is from my index (ion-nav-bar).
thank you.
index.html
<body ng-app="starter">
<!--
The nav bar that will be updated as we navigate between views.
-->
<ion-nav-bar class="bar-stable">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<!--
The views will be rendered in the <ion-nav-view> directive below
Templates are in the /templates folder (but you could also
have templates inline in this html file if you'd like).
-->
<ion-nav-view class="slide-left-right"></ion-nav-view>
</body>
</html>
login.html
<ion-view view-title="Login" name="login-view">
<ion-content class="padding">
<h1>lalalalala</h1>
<div class="list">
<label class="item item-input">
<span class="input-label">Username</span>
<input type="text">
</label>
<label class="item item-input">
<span class="input-label">Password</span>
<input type="password">
</label>
</div>
<button class="button button-block button-calm" ng-click="login()">Login</button>
</ion-content>
</ion-view>
app.js
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleLightContent();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
// Each tab has its own nav history stack:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
.state('tab.dash', {
url: '/dash',
views: {
'tab-dash': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
.state('tab.projects', {
url: '/projects',
views: {
'tab-projects': {
templateUrl: 'templates/tab-projects.html',
controller: 'projectsCtrl'
}
}
})
.state('tab.projects-detail', {
url: '/projects/:projectsId',
views: {
'tab-projects': {
templateUrl: 'templates/projects-detail.html',
controller: 'projectsDetailCtrl'
}
}
})
.state('tab.account', {
url: '/account',
views: {
'tab-account': {
templateUrl: 'templates/tab-account.html',
controller: 'AccountCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('login');
});
controllers.js
angular.module('starter.controllers', [])
.controller('loginCtrl', function($scope) {})
.controller('DashCtrl', function($scope) {})
.controller('projectsCtrl', function($scope, Chats) {
$scope.chats = Chats.all();
$scope.remove = function(chat) {
Chats.remove(chat);
}
})
.controller('ChatDetailCtrl', function($scope, $stateParams, Chats) {
$scope.chat = Chats.get($stateParams.chatId);
})
.controller('AccountCtrl', function($scope) {
$scope.settings = {
enableFriends: true
};
});
I guess the problems is in your default route:
$urlRouterProvider.otherwise('/tab/login');
You have defined it depending from the abastract tab:
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
and this is your login:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
the state name is tab.login which means it inherits from tab.
so your root is /tab/login.
this should be your tabs.html:
<ion-tabs class="tabs-icon-top tabs-color-active-positive">
<ion-tab title="Login" icon-off="ion-ios-pulse" icon-on="ion-ios-pulse-strong" href="#/tab/login">
<ion-nav-view name="login"></ion-nav-view>
</ion-tab>
<ion-tab title="Status" icon-off="ion-ios-pulse" icon-on="ion-ios-pulse-strong" href="#/tab/dash">
<ion-nav-view name="tab-dash"></ion-nav-view>
</ion-tab>
</ion-tabs>
as you can see your ion-nav-view name:
<ion-nav-view name="login"></ion-nav-view>
must match the one defined in your state:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'login.html',
controller: 'loginCtrl'
}
}
})
You don't need to set the view's name here (login.html):
<ion-view view-title="Login" name="login-view">
Another thing I've noticed, you use the same name for two different views: tab-projects
:
.state('tab.projects', {
url: '/projects',
views: {
'tab-projects': {
templateUrl: 'templates/tab-projects.html',
controller: 'projectsCtrl'
}
}
})
.state('tab.projects-detail', {
url: '/projects/:projectsId',
views: {
'tab-projects': {
templateUrl: 'templates/projects-detail.html',
controller: 'projectsDetailCtrl'
}
}
})
another thing has more to do with conventions. If you use for your views names starting with tab-, probably you should do the same for the login.
Here is a plunker with some of your code.
Change your app.js to
.state('login', {
url: '/login',
controller: 'LoginCtrl',
templateUrl: 'templates/login.html'
})
and $urlRouterProvider.otherwise('/login');
If you place your login.html
in correct folder then there is not going to be any problem.
I've been putting comments regarding your code, so let me formulate an answer with some steps you would like to follow
1:
You have a mess once you declare your controllers, try to follow a guide like this, at least declare your controllers/services/directives and so on in the same way, LoginCtrl
and not loginCtrl
and the other stuff with no capital as a first letter. It is just an advise my friend.
2:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
here something you need to check, the name of your view, you have login
but
<ion-view view-title="Login" name="login-view">
...
</ion-view>
so change it to login
only. And do the same in your abstract
route.
like this
<ion-view view-title="Login" name="login">
And this so important
$urlRouterProvider.otherwise('/login');
which goes at the end of the $stateProvider
. The otherwise
method will always redirect to /login
in case that any other route it's been matched
You should give a name to your <ion-nav-view>
in your index.html
template.
e.g. <ion-nav-view name="viewContent"></ion-nav-view>
Then, in your routes, you specify into which part of your app you want your template to be rendered, e.g.:
.state('login', {
url: '/login',
views: {
'viewContent': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
this will render templates/login.html
into the viewContent
area.
That's why UI-router is so flexible, because you can tell it exactly which parts should be replaced when routing.
If you don't need that flexibility, just write your routes without the views
part and add controller
and templateUrl
directly to each state.
also your fallback probably should be $urlRouterProvider.otherwise('/login');
If you want to evaluate a success at login to show certain views should not be in the same state.
This should be true:
.state('login',{
url: "/login",
views : {
'menuContent' : {
templateUrl : "login.html",
controller : "LoginCtrl"
}
}
})
$urlRouterProvider.otherwise("/login");
Follow the order as advice or guide on how to write their app.js
<script id="login.html" type="text/ng-template">
<ion-view view-title="Login" name="login-view">
<ion-content class="padding">
<h1>lalalalala</h1>
<div class="list">
<label class="item item-input">
<span class="input-label">Username</span>
<input type="text">
</label>
<label class="item item-input">
<span class="input-label">Password</span>
<input type="password">
</label>
</div>
<button class="button button-block button-calm" ng-click="login()">Login</button>
</ion-content>
</ion-view>
</script>