I have a < ion-side-menu > with links to my pages defined here:
app.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
$stateProvider.state('content', {
url: "/content",
abstract: true,
templateUrl: "templates/sidemenu.html",
controller: 'SideController'
});
$stateProvider.state('content.home', {
url: "/home",
views: {
'menuContent': {
templateUrl: "templates/home.html",
controller: "HomeController"
}
}
});
$stateProvider.state('content.nearby', {
url: "/nearby",
views: {
'menuContent': {
templateUrl: "templates/nearby.html",
controller: "NearbyController"
}
}
});
$stateProvider.state('content.map', {
url: "/map",
views: {
'menuContent': {
templateUrl: "templates/map.html",
controller: "MapController"
}
}
});
$stateProvider.state('content.radar', {
url: "/radar",
views: {
'menuContent': {
templateUrl: "templates/radar.html",
controller: "RadarController"
}
}
});
$stateProvider.state('content.location-details', {
url: "/location-details/:index",
views: {
'menuContent': {
templateUrl: "templates/location-details.html",
controller: "DetailsController"
}
},
resolve: {
currentLocation: function($stateParams, shareService, NearbyFactory)
{
return NearbyFactory.getLocations()[$stateParams.index];
}
}
});
$urlRouterProvider.otherwise("/content/home");
});
I want to execute a method in my controllers when the user navigates to this page and when the page is left (for loading AJAX data or start listening to some Cordova sensors). Like this:
app.controller("HomeController", function()
{
$scope.onEnter = function(previous_page)
{
...
};
$scope.onExit = function(next_page)
{
...
};
});
I've already tried onEnter and onExit inside the $stateProvider state but afaik I don't have my $scope there.
What is the easiest/best/nicest way to get this functionality? It would be great if I could determine the previous/next page and if the user navigated back/forward. I tried this:
$scope.$on('$routeChangeStart', function(event, next, current)
{
console.log(next);
});
but this didn't work every time and it didn't fire when loading the page. This also seems a bit dirty to me because I'd have to implement this in every single controller.
Thank you!
You can use $ionicView.beforeEnter and beforeLeave.
Simply add this to your HomeController :
app.controller("HomeController", function()
{
$scope.$on('$ionicView.beforeEnter', function() {
//do stuff before enter
});
$scope.$on('$ionicView.beforeLeave', function() {
//do your stuff after leaving
});
});
You can check the docs of the $ionicView here.
You can try this. It works every time when it's loading the page:
$scope.$on('$locationChangeStart', function(event)
{
console.log(event);
});
Related
Hi I have been using stateprovider for a long time and this time I want to implement a functionality in which without changing the url, I want to go not found state but not on url.
This is my code.
(function () {
angular.module('mean').config(aosOfferConfig);
function aosOfferConfig($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/link/404_not_found");
$stateProvider
.state('offers', {
url: '/offers/packages',
templateUrl: 'views/aosOffers/aosoffers.html',
controller: 'offersController',
controllerAs: 'packages'
})
.state('offersignup', {
url: '/offers/signup',
templateUrl: 'views/aosOffers/offerssignup.html',
controller: 'offersSignupController',
controllerAs: 'offerssignup'
})
.state('thankyou', {
url: '/offers/thankyou',
templateUrl: 'views/aosOffers/offersthankyou.html'
});
}
})();
Now in my otherwise part I am taking the user to /link/404_not_found. I don't want this. Instead, I want that it will remain in current url but the state should be changed. Just like github does.
How can I do this ?
do it this way
(function () {
angular.module('mean').config(aosOfferConfig);
function aosOfferConfig($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise(function ($injector, $location) {
var state = $injector.get('$state');
state.go('404_not_found', {}, { location: false });
return $location.path();
});
$stateProvider
.state('offers', {
url: '/offers/packages',
templateUrl: 'views/aosOffers/aosoffers.html',
controller: 'offersController',
controllerAs: 'packages'
})
.state('offersignup', {
url: '/offers/signup',
templateUrl: 'views/aosOffers/offerssignup.html',
controller: 'offersSignupController',
controllerAs: 'offerssignup'
})
.state('thankyou', {
url: '/offers/thankyou',
templateUrl: 'views/aosOffers/offersthankyou.html'
})
.state('404_not_found', {
template: '<h1>Notfound</h1>'
});
}
})();
In my app I am trying to dashboard.html and associated controller would load if the condition is true, but the problem is first time it will load the controller but from second time it is opening html page but not only loading controller.
What may the wrong where I did mistake please help me to find.
app.js
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
})
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AutoLoginCtrl'
})
.state('app.autoLog', {
url: '/autoLog',
controller: 'AutoLoginCtrl'
})
.state('app.search', {
url: '/search',
views: {
'menuContent': {
templateUrl: 'templates/search.html'
}
}
})
.state('app.browse', {
url: '/browse',
views: {
'menuContent': {
templateUrl: 'templates/browse.html'
}
}
})
.state('app.profileInfo', {
url: '/profileInfo/:success',
views: {
'menuContent': {
templateUrl: 'templates/profileInfo.html',
controller: 'ProfileCtrl'
}
}
})
.state('app.profile', {
url: '/profile/:data',
views: {
'menuContent': {
templateUrl: 'templates/profile.html',
controller: 'ProfileCtrl'
}
}
})
.state('app.dashboard', {
url: '/dashboard',
views: {
'menuContent': {
templateUrl: 'templates/dashboard.html'
}
}
})
.state('app.dog', {
url: '/dog',
views: {
'menuContent': {
templateUrl: 'templates/dog.html',
controller: 'ProfileCtrl'
}
}
});
$urlRouterProvider.otherwise('/app/autoLog');
loginController.js
If the below condition is true then is will call .state('app.dashboard')
if (data[0].Userprofile1 == true && data[0].Userprofile2 == true) {
$ionicLoading.hide();
console.log('My profile setup is over');
$state.go("app.dashboard");
}
dashboardController.js
app.controller('dashboardCtrl', function($scope, $http, $state, UserService) {
$scope.pageName = 'Hi i am user';
console.log('Hi home controller loading')
var userStatus = UserService.getUser()
console.log(userStatus);
if (userStatus != null) {
$scope.ersrserer = userStatus.userID;
console.log($scope.ersrserer);
} else {
console.log('its empty');
}
})
first time when it calls dashboard.html it will load controller also but from second time it will not load controller, what went wrong here?
A state requires a controller to be initialized with it, you have add the controller and inside the state you can add a resolve block:
.state('your state', {
url: '/url',
resolve: {
someName: function(inject here) {
//return something, or redirect to a state...etc
}
},
templateUrl: 'templates/something.html',
controller: 'ExampleCtrl'
})
This code is functional, but it could work better. My question:
How i can insert navDetalle or other views in many states without call controller again.
(function() {
'use strict';
angular
.module('miApp')
.config(routerConfig);
var nav = {
templateUrl: 'app/nav/nav.html',
controller: 'NavController',
controllerAs: 'nav'
};
var navInter = {
templateUrl: 'app/nav/navInter.html',
controller: 'NavController',
controllerAs: 'nav'
};
var navDetalle = {
templateUrl: 'app/navDetalle/navDetalle.html',
controller: 'NavDetalleController',
controllerAs: 'navDetalle'
};
/** #ngInject */
function routerConfig($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
views: {
// the main template will be placed here (relatively named)
'nav': nav,
'carousel': {
templateUrl: 'app/carousel/carousel.html',
controller: 'CarouselController',
controllerAs: 'carousel'
},
'footer':{
templateUrl: 'app/footer/footer.html'
}
}
})
.state('detalle', {
url: '/detalle/:idDetalle',
views:{
'nav': navInter,
'detalle': {
templateUrl: 'app/detalle/detalle.html',
controller: 'DetalleController',
controllerAs: 'detalle'
},
'navdetalle': navDetalle,
'footer':{
templateUrl: 'app/footer/footer.html'
}
}
})
.state('resumen', {
url: '/resumen',
views:{
'nav': navInter,
'navdetalle': navDetalle,
'footer':{
templateUrl: 'app/footer/footer.html'
}
}
})
.state('success', {
url: '/success',
views:{
'nav': navInter,
'success': {
templateUrl: 'app/success/success.html',
controller: 'SuccessController',
controllerAs: 'success'
},
'navdetalle': navDetalle,
'footer':{
templateUrl: 'app/footer/footer.html'
}
}
})
.state('cancel', {
url: '/cancel',
views:{
'nav': navInter,
'navdetalle': navDetalle,
'cancel': {
templateUrl: 'app/cancel/cancel.html',
controller: 'CancelController',
controllerAs: 'cancel'
},
'footer':{
templateUrl: 'app/footer/footer.html'
}
}
});
$urlRouterProvider.otherwise('/');
}
})();
and if you have suggestion on another improvements please comment
I'm not sure if this is possible to prevent executing controller every time. But, I do have another solution. That might work. The Ionic Framework do this internally by preserving controller state.
Create a global controller and add it to <body> or <html> tag so that its scope can be available every time.
app.controller('GlobalController', function($scope) {
var navDetalleCtrlInstantiated = false;
$scope.$on('$stateChangeStart', function(e, toState, toParams) {
if (!navDetalleCtrlInstantiated && toState.views && toState.views.navdetalle) {
// Do the common logic on controller instantiation
// Mark so that we don't have to do the same logic again
navDetalleCtrlInstantiated = true;
}
});
});
In your view:
<body ng-controller="GlobalController">
</body>
And remove logic from your NavDetalleController.
I don't know if what you want is possible. Because ui-router always creates a new instance to the view's controller, and that makes sense cause every single view has your own scope.
Hi i am new to ionic framework. i am using session manager in ionic. But i want to skip login page if user is already logged in.
app.js
angular.module('grocery', ['ionic', 'grocery.controller', 'ngCordova', 'ngCordovaOauth'])
.run(function($ionicPlatform, $cordovaSQLite, $cordovaToast, $rootScope, mainItemsList, $state) {
$ionicPlatform.ready(function() {
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
stops the viewport
// from snapping when text inputs are focused. Ionic handles this internally for
// a much nicer keyboard experience.
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
});
$rootScope.$on('$locationChangeStart', function(event, newUrl, oldUrl) {
if (mainItemsList.isLoggedIn() != true) {
$state.go('app.login');
}
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/navigationDrawer.html",
controller: 'AppCtrl'
})
.state('app.masterList', {
url: "/masterList",
views: {
'menuContent': {
templateUrl: "templates/masterList.html",
controller: 'indexCtrl'
}
}
})
.state('app.login', {
url: "/login",
views: {
'menuContent': {
templateUrl: "templates/login.html",
controller: 'loginCtrl'
}
}
})
.state('app.register', {
url: "/register",
views: {
'menuContent': {
templateUrl: "templates/register.html",
controller: 'registerCtrl'
}
}
})
$urlRouterProvider.otherwise("/app/masterList");
});
angular.module('grocery.services', [])
.factory('mainItemsList', function($cordovaSQLite, $cordovaToast, $cordovaPreferences) {
return {
isLoggedIn: function(sessionEmail) {
$cordovaPreferences.store('email', sessionEmail).success(function(value) {
//$cordovaToast.showShortTop('stored');
})
.error(function(error) {
$cordovaToast.showShortTop("Error " + error);
})
return true;
}
}
})
I tried existing stackoverflow answers. But not working. please help me where i am wrong.
Create a new controller and a new state called autologin. Make this your default state. In the autologin controller, check whether the user is already logged in. If he is, redirect to some page. If he is not, redirect to login.
.state('app.autologin', {
url: "/autologin",
controller: 'autologinCtrl'
})
$urlRouterProvider.otherwise("/app/autologin");
controller:
angular.module('grocery').controller('autologinCtrl, function($scope, $state){
//check if user is logged in
if (userLoggedIn){
state.go('app.masterList');
} else {
state.go('app.login');
}
});
If you are adding a new controller for this logic,There will be a chance for flickering between the pages.So handle this by using $urlRouterProvider
.config(function($stateProvider, $urlRouterProvider, mainItemsList) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/navigationDrawer.html",
controller: 'AppCtrl'
})
.state('app.masterList', {
url: "/masterList",
views: {
'menuContent': {
templateUrl: "templates/masterList.html",
controller: 'indexCtrl'
}
}
})
.state('app.login', {
url: "/login",
views: {
'menuContent': {
templateUrl: "templates/login.html",
controller: 'loginCtrl'
}
}
})
.state('app.register', {
url: "/register",
views: {
'menuContent': {
templateUrl: "templates/register.html",
controller: 'registerCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise(function() {
var logged = mainItemsList.isLoggedIn();
// Check User logined or not
if (logged != true) {
return 'app.login';
} else {
return 'app.masterList';
}
});
});
When using ui-router's $state.go() in my Ionic app, the onEnter method is not called.
The states would be transitioning from tab.settings to tab.queries. The state transitions fine. How do I get the onEnter method to be called from $state.go() call? Does onEnter not get called when entering child views?
Route
$stateProvider
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
.state('tab.queries', {
url: '/queries',
views: {
'tab-queries': {
templateUrl: 'templates/tab-queries.html',
controller: 'QueryCtrl',
onEnter: function() {
activate();
}
}
}
})
.state('tab.settings', {
url: '/settings',
views: {
'tab-settings': {
templateUrl: 'templates/tab-settings.html',
controller: 'SettingsCtrl'
}
}
});
SettingsCtrl
vm.removeAll = function() {
Data.removeAll().then(function() {
$state.go('tab.queries');
});
};
QueryCtrl
function activate() {
console.log('Activating');
}
Try moving the onEnter from within the view object up a level to the state object, I've just ran across this same problem and it seemed to work OK for me.
.state('tab.queries', {
url: '/queries',
views: {
'tab-queries': {
templateUrl: 'templates/tab-queries.html',
controller: 'QueryCtrl'
}
},
onEnter: function() {
activate();
}
})