I want to know how $ionicHistory internally works . If i call a function named goBack() inside will it work fine . Or any other tags i need to add in my html code . Please help me out with your suggestions .
i have used both
$scope.goBack = function() {
console.log('Going back');
$ionicViewService.getBackView().go();
}
or
$scope.goBack = function() {
console.log('Going back');
$ionicHistory.goBack();
}
I tried both approach . everytime i am getting same output . you can see where 2nd logout is there , I am trying to navigate from that page to 1st page(1st logout ). But it's coming like this . Please help me out how to resolve this .
Thanks #Sa E Chowdary Finally my code worked
Few changes i made in my js file
.state('app.profile', {
cache: false,// disabled cache
url: './profile',
views: {
'menuContent': {
// templateUrl: 'templates/profile.html',
templateUrl: 'templates/profile.html',
controller: 'ProfileCtrl'
},
'fabContent': {
template: ''
}
}
})
in my controller
setTimeout(
function()
{ $scope.goBack = function() {
console.log('Going back');
$ionicHistory.goBack();
// window.history.go(-1);
};
}, 2000);
Main changes i did is disabled cache otherwise $ionicHistory was not behaving properly .
Again Thanks All
According to the documentation,it will track the views while user navigating in the application....an Ionic app is able to keep track of the previous view, the current view, and the forward view (if there is one).
And it contains some methods you can found in documentation....
coming to your case you need to write some code in your js according to your requirement like whether you want to go to previous view or next view and dont forgot to add or inject the dependency....
you need to use something like this
$ionicHistory.nextViewOptions({
//your code
});
and
$ionicHistory.backView({
//your code
})
you may use $ionicViewService also and you can find there how it will works
yes goBack() will also work in your controller code.
use like this : $ionicHistory.goBack();
Read the documentation
Related
it's probably a rookie mistake but I am having trouble changing my page using:
$state.go('login');
My routing looks as following:
$stateProvider
.state('login', {
url: "/login",
templateUrl: "./auth/login.html",
controller: 'loginCtrl'
})
I also added a
$rootScope.$on("$stateChangeStart", function (event, next) {...}
just to check if it gets there after I use $state.go() and yes; it gets there but it does not change my page or URL at all. Changing the page works fine with ui-sref="login" inside a view.html.
Other syntaxes I tried:
$state.go('login', null, {options: { location : true } } );
$state.go('login', {}, {location : true});
Btw, what I am trying to accomplish is redirecting to a login-page when the user is not authorized inside the $stageChangeStart-event.
Any ideas?
Visit Angular ui router - Redirection doesn't work at all . It gave me a more clear idea of what I was doing wrong.
The actual solution for me was found at the following page answered by frankwallis:
https://github.com/angular-ui/ui-router/issues/600
I replaced my default $urlRouterProvider.otherwise('/yourpage'); with
$urlRouterProvider.otherwise( function($injector, $location) {
var $state = $injector.get("$state");
$state.go("app.home");
});
Too bad I don't really understand the solution but atleast it works now!
I am trying to move one view to another on button click> I am able to move one one view to second .But while moving it start slide from right to left .I need to stop that sliding . mean I need to learn various type of way to move one view to another using animation (left to right or up to down or no animation or down to up) .
Check my code here
http://goo.gl/Q2k6mf
click preview button .And type "ABW" and select "ABW" row .it download data from server and after that it move to second view with sliding why ? I need to stop that sliding .
Secondly
I am downloading the data in first controller .is there any better way to hit server or call webservice before moving to second view ?
$scope.rowclick=function(station){
$scope.SEARCH.stationCode=station.stationCode;
$scope.SEARCH.selected = true;
$ionicLoading.show();
$http.get("http://caht.firstrail.com/FGRailApps/jservices/rest/a/departure?crsCode="+ $scope.SEARCH.stationCode).then(function(data){
$ionicLoading.hide();
$state.go('departuredashboard')
console.log(data);
},function(error){
$ionicLoading.hide();
alert("error"+error);
})
}
Actually I need that data on second view ?
here is code
https://dl.dropbox.com/s/l2dtrxmnsurccxt/www.zip?dl=0
I don't know why you want to remove that animation, Its so sweet, but here you go.
app.config(function($stateProvider, $urlRouterProvider,$ionicConfigProvider){
$ionicConfigProvider.views.transition('none')
// rest of the config
})
Edit: For your second question: here is a code snippet as to how to use resolve of ui-router
.state('stateName',{
url:'/SomeUrl',
resolve: {
resolvedData: function ($http) {
var result = $http.get(yourUrlHere).success(function (data) {
return data;
}).error(function (err) {
return err;
});
return result;
}
}
})
And in your controller , inject "resolvedData"
To disable navigation transitions use $ionicConfigProvider
$ionicConfigProvider.views.transition('none') in config box
To load data before controller user resolve:
app.config(function($stateProvider, $urlRouterProvider,$ionicConfigProvider) {
$stateProvider
.state('index', {
url: '/',
templateUrl: 'template1.html'
})
.state('state2', {
url: '/state2',
templateUrl: 'template2.html',
controller: 'ACtrl',
resolve:{ myData : ['$http',function($http) {
var ULR ="your URL";
return $http.get(URL);
}]}
})
});
Now you can insert myData in your second controller just like any other Service.
I'm starting out with Angular through the Ionic Framework but I am failing to understand why the controller only runs once i.e. I change state, the controller runs, change to another state and then back again and the controller does not run a second time. This is my state:
$stateProvider.state( 'container.previous', {
url: 'previous',
views: {
main : {
templateUrl : 'views/previous.html',
controller : function( $scope, $cordovaSQLite ){
$scope.firms = [];
$cordovaSQLite.execute(window.db, "SELECT * FROM recent GROUP BY phone ORDER by id DESC").then(function(res) {
for (i = 0; i < res.rows.length; i++) {
$scope.firms.push(res.rows.item(i));
}
}, function (err) {
console.error(err);
});
}
}
},
onStateChangeStart : function(){
backButton = true;
}
});
In another state, if you click on a button related to a "firm", it saves the "firms" data to local storage. The above state shows the firms in which you have previously clicked on. But I cannot figure out how to update the $scope.firms correctly as the controller never runs again.
Can anyone help me out?
You can put the code you want to run in $ionicView.enter:
controller : function( $scope, $cordovaSQLite ){
$scope.$on('$ionicView.enter', function() {
// code to run each time view is entered
});
...
});
See "View LifeCycle and Events": https://ionicframework.com/docs/v1/api/directive/ionView/
Building on #brandyshea's answer, I would like to add if you want to specify no caching in one area/controller/state, and take advantage of the caching in other areas, you can simply use the cache parameter in your $stateProvider for that state.
Disable cache within state provider
$stateProvider.state('myState', {
cache: false,
url : '/myUrl',
templateUrl : 'my-template.html'
})
Alternatively, you can use one of the other methods too:
Disable cache with an attribute
<ion-view cache-view="false" view-title="My Title!">
...
</ion-view>
Disable cache globally
The $ionicConfigProvider can be used to set the maximum allowable views which can be cached, but this can also be use to disable all caching by setting it to 0.
$ionicConfigProvider.views.maxCache(0);
References: http://ionicframework.com/docs/api/directive/ionNavView/ and http://ionicframework.com/docs/api/directive/ionView/
You don't need to disable entire app cache.
If you want to re-run controller every time you enter on it you should clear cache before you leave it:
$scope.$on("$ionicView.afterLeave", function () {
$ionicHistory.clearCache();
});
Ionic has a cache mechanism inside. You can disable caching globally in your config function like this :
$ionicConfigProvider.views.maxCache(0);
Put this in your ion-view.
<ion-view cache-view="false">
I like the ability for Angular's router to 'resolve' data for me before transferring control to a controller. How can I show something to the user (spinner, "loading...", etc.) while waiting for a route's resolve function to complete, in the case of an ajax call getting run for the resolve function?
Here's an example from a router that shows what I mean:
.when('/users/:userId/profile', {
templateUrl: 'views/profile.html',
controller: 'ProfileCtrl',
resolve: {
userProfile: ['$route', 'ProfileService', function ($route, ProfileService) {
return ProfileService.loadProfile($route.current.params.userId);
}]
}
})
As I understand it, "ProfileCtrl" does not get created until "userProfile" has been resolved. That means I can't put code there to run while waiting for the resolve function to complete. In my case "ProfileService.loadProfile" makes and HTTP request, so for the sake of this example, let's say it takes a few seconds to return.
What's the recommended way to show something to the user while waiting for this?
You can use $routeChangeStart and $routeChangeSuccess to set some boolean that is used to display a loading animation or whatever in your view:
angular.module('myApp').run(function($rootScope) {
$rootScope.$on('$routeChangeStart', function() {
$rootScope.isLoading = true;
})
$rootScope.$on('$routeChangeSuccess', function() {
$rootScope.isLoading = false;
})
})
in your template you'd have something like:
<div class='loading' ng-show='isLoading'></div>
Or since that is linked to a template which may or may not be available, put class on the page body:
<body ng-class='loading: isLoading'>
</body>
and style it however you like.
As per https://docs.angularjs.org/api/ngRoute/service/$route 'Once all of the dependencies are resolved $routeChangeSuccess is fired.' There is also routeChangeError if you want to tell users when there is a problem with your ajax/resolve. ui-router has analogous stateChangeStart etc.
I can't figure out a reasonable way, which doesn't feel like a hack, to solve this rather trivial problem.
I want a guest to see a splash page when they access the index of the website and a logged in user to see their profile, with each page having it's own template and controller. Ideally, there would be two states for one url, and somehow I would be able to automatically alter the active one depending on the loggin status. Both of these views will have their own nested views so ng-include cannot be used (I assume).
I'm quite new to angular and ui router and think I might be overlooking an easy solution to the problem.
Could it be done with named views and ng-show?
If you're using UI Router, just create three states: the root state, with the '/' URL, and two direct descendant states with no URLs. In the onEnter of the root state, you detect the state of the user and transition to the correct child state accordingly. This gives the appearance of keeping the same URL for both child states, but allows you to have to separate states with separate configurations.
The templateUrl can be a function as well so you can check the logged in status and return a different view and define the controller in the view rather than as part of the state configuration
My Solution:
angular.module('myApp')
.config(function ($stateProvider) {
$stateProvider
.state('main', {
url: '/',
controller: function (Auth, $state) {
if (someCondition) {
$state.go('state1');
} else {
$state.go('state2');
}
}
});
});
where state 1 and state 2 are defined elsewhere.
For docs purposes, I used:
$rootScope.$on('$stateChangeStart', function(event, toState) {
if ((toState.name !== 'login') && (!$localStorage.nickname)) {
event.preventDefault();
$state.go('login');
}
});
Using $routeChangeStart didn't work for me.
It is used for me conditional view in ui-route
$stateProvider.state('dashboard.home', {
url: '/dashboard',
controller: 'MainCtrl',
// templateUrl: $rootScope.active_admin_template,
templateProvider: ['$stateParams', '$templateRequest','$rootScope', function ($stateParams, templateRequest,$rootScope) {
var templateUrl ='';
if ($rootScope.current_user.role == 'MANAGER'){
templateUrl ='views/manager_portal/dashboard.html';
}else{
templateUrl ='views/dashboard/home.html';
}
return templateRequest(templateUrl);
}]
});
If I understand the question; you want to make sure that the user who hasn't logged in cannot see a page that requires log in. Is that correct?
I've done so with code like this inside a controller:
if(!'some condition that determines if user has access to a page'){
$location.path( "/login" );
}
Anywhere (probably in some high-level controller) you should be able to just bind a '$routeChangeStart' event to the $rootScope and do your check then:
$rootScope.$on('$routeChangeStart', function(next, current){
if(next != '/login' && !userLoggedIn){
$location.path( "/login" );
}
});
This will get fired every time a new route is set, even on the first visit to the page.
The way I've done this is pretty simple. I made one for our A/B testing strategy. This is the gist:
resolve: {
swapTemplate: function(service) {
// all of this logic is in a service
if (inAbTest) {
this.self.templateUrl = '/new/template.html';
}
}
... other resolves
}
This gets called before the template is downloaded and therefor you're allowed to swap out the template url.
In my case, if two states can share logic of same controller, conditional template is a good choice. Otherwise, creating separate states is a good option.