I'm playing with this ionicView events that are fired whenever the views become active, and I'm using the side menu template that you can re-use when creating the project. It seems that if I put a listener for the $ionicView.entered event in the AppCtrl (the one used by the side menu template, which belongs to an abstract state in the ui-router configuration) it gets called twice in a row for any of the subviews (like, when using app.someotherview as a state).
I don't know if this is the expected behavior because from the documentation I would expect it to only fire once, no matter if I change the subview (the menuContent view).
I'd like to know if this is expected behavior and if so, how do I get to have an event fired only once every time it gets to show the side menu template.
This is what I've got written:
This is from the application module:
.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('app.overview', {
url: "/overview",
views: {
'menuContent': {
templateUrl: "templates/overview.html",
controller: 'OverviewCtrl'
}
}
})
.state('login', {
url: "/login",
templateUrl: "templates/identificationscreen.html",
controller: "IdentificationCtrl"
})
.state('app.agenda', {
url: "/agenda",
views: {
'menuContent': {
templateUrl: "templates/agenda.html",
controller: 'AgendaCtrl'
}
}
});
$httpProvider.interceptors.push('credentialsInjector');
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/login');
Then the AppCtrl is this:
angular.module('dashboard.controllers.app', [])
.controller('AppCtrl', function($scope, $ionicModal, $timeout, $ionicSideMenuDelegate, authService, $state) {
$scope.logout = function() {
authService.logout();
$state.go('login');
};
$scope.$on('$ionicView.enter', function(){ //This is fired twice in a row
console.log("App view (menu) entered.");
console.log(arguments);
});
$scope.$on('$ionicView.leave', function(){ //This just one when leaving, which happens when I logout
console.log("App view (menu) leaved.");
console.log(arguments);
});
});
The menu template:
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content edge-drag-threshold="true">
<ion-nav-bar class="bar-stable">
<ion-nav-back-button>
</ion-nav-back-button>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left">
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-header-bar class="bar-stable">
<h1 class="title">APPoint!</h1>
</ion-header-bar>
<ion-content>
<ion-list>
<ion-item nav-clear menu-close href="#/app/overview">
Overview
</ion-item>
<ion-item nav-clear menu-close href="#/app/agenda">
Agenda
</ion-item>
<ion-item nav-clear menu-close ng-click="logout()">
Logout
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
I'm playing with this ionicView events that are fired whenever the views become active, and I'm using the side menu template that you can re-use when creating the project. It seems that if I put a listener for the $ionicView.entered event in the AppCtrl (the one used by the side menu template, which belongs to an abstract state in the ui-router configuration) it gets called twice in a row for any of the subviews (like, when using app.someotherview as a state).
I don't know if this is the expected behavior because from the documentation I would expect it to only fire once, no matter if I change the subview (the menuContent view).
I'd like to know if this is expected behavior and if so, how do I get to have an event fired only once every time it gets to show the side menu template.
This is what I've got written:
This is from the application module:
.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('app.overview', {
url: "/overview",
views: {
'menuContent': {
templateUrl: "templates/overview.html",
controller: 'OverviewCtrl'
}
}
})
.state('login', {
url: "/login",
templateUrl: "templates/identificationscreen.html",
controller: "IdentificationCtrl"
})
.state('app.agenda', {
url: "/agenda",
views: {
'menuContent': {
templateUrl: "templates/agenda.html",
controller: 'AgendaCtrl'
}
}
});
$httpProvider.interceptors.push('credentialsInjector');
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/login');
Then the AppCtrl is this:
angular.module('dashboard.controllers.app', [])
.controller('AppCtrl', function($scope, $ionicModal, $timeout, $ionicSideMenuDelegate, authService, $state) {
$scope.logout = function() {
authService.logout();
$state.go('login');
};
$scope.$on('$ionicView.enter', function(){ //This is fired twice in a row
console.log("App view (menu) entered.");
console.log(arguments);
});
$scope.$on('$ionicView.leave', function(){ //This just one when leaving, which happens when I logout
console.log("App view (menu) leaved.");
console.log(arguments);
});
});
The menu template:
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content edge-drag-threshold="true">
<ion-nav-bar class="bar-stable">
<ion-nav-back-button>
</ion-nav-back-button>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left">
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-header-bar class="bar-stable">
<h1 class="title">APPoint!</h1>
</ion-header-bar>
<ion-content>
<ion-list>
<ion-item nav-clear menu-close href="#/app/overview">
Overview
</ion-item>
<ion-item nav-clear menu-close href="#/app/agenda">
Agenda
</ion-item>
<ion-item nav-clear menu-close ng-click="logout()">
Logout
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
Share
Improve this question
edited May 14, 2015 at 12:06
Adrián Pérez
asked May 14, 2015 at 11:38
Adrián PérezAdrián Pérez
2,2164 gold badges22 silver badges33 bronze badges
1
- @andrian you got solution for this issue? – Tummala Krishna Kishore Commented Dec 21, 2015 at 7:39
5 Answers
Reset to default 10A simple workaround is:
$scope.$on('$ionicView.enter', function(ev) {
if(ev.targetScope !== $scope)
return;
// Your code which should only run once
});
The best option that I found to simulate onEnter event was to use in view controller :
$scope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
if (toState.name == "stateName")
doSomething();
}
You can globally disable the caching mechanism used by ionic by doing:
$ionicConfigProvider.views.maxCache(0);
I haven't tried that on my own though.
Else, the best way that worked for me was doing
$scope.$on("$ionicView.afterLeave", function () {
$ionicHistory.clearCache();
});
This is to clear the cache before leaving the view to re-run controller every time you enter back again.
Try $ionicView.afterEnter
. That fires only once for me.
URL
At first I used Florian's answer but noticed that in my case it's just a symptom of a root problem, because this doesn't happen to all controllers, just this one.
In my case, it happens because I was trying to incrementally migrate from Ionic/AngularJS v1 to Ionic/AngularJS v2.
I have added controllerAs
in my template:
<ion-view view-title="Avatar » Instruments" ng-controller="AvatarInstrumentsCtrl as vm">
but I forgot to remove the controller reference in my app.js
:
.state('app.avatar-instruments', {
url: "/avatar/instruments",
views: {
'menuContent': {
templateUrl: "templates/avatar/instruments.html",
controller: 'AvatarInstrumentsCtrl'
}
}
})
So in my case the solution is:
.state('app.avatar-instruments', {
url: "/avatar/instruments",
views: {
'menuContent': {
templateUrl: "templates/avatar/instruments.html"
}
}
})