I have an Ionic app where I want the controller to reload whenever a user visits a tab. I have the following link here...
<ion-tab icon-off="ion-ios-person-outline" icon-on="ion-ios-person" ui-sref="tab.profile({reload: true})">
<ion-nav-view name="tab-profile"></ion-nav-view>
</ion-tab>
If I visit the tab link once, the controller loads(obviously). If I leave the page and click that same link again the page does not reload. The way I'm detecting this page reload by injecting a console.log into the controller file.
angular.module('coolsite.user')
.controller('ProfileController', profileController)
profileController.$inject = [];
function profileController( ) {
var vm = this;
console.log("activated");
}
How do I reload the controller every time the user clicks on the link?
You should use transitionTo to reload your controller & route.
Markup
<ion-tab icon-off="ion-ios-person-outline" icon-on="ion-ios-person" ng-click="vm.redirect('tab.profile')">
<ion-nav-view name="tab-profile"></ion-nav-view>
</ion-tab>
Controller
vm.redirect = function(stateName){
$state.transitionTo(stateName, {} , {
reload: true,
inherit: false,
notify: true
});
}
Update
Though it was not related to angular-ui-router Its specifically related to ionic-view, they getting cached by default. You need can disable those caching by state just by mentioning cache: false.
Code
.state('tab.profile', {
url: '/profile',
views: {
'tab-profile': {
templateUrl: 'templates/tabs/profile.html',
controller: 'ProfileController as profile',
reload: true
}
},
cache: false
})
There are also two alternative way to achieve this, you can find it in this answer with better explanation which is given by me only
So, I think what you're really looking to do is not use the cache. That means that in your state, you'll want to set cache: false. To be clear, controllers are not "reloaded." The scope is simple removed and re-added when you return to the page, unless you set the cache to false.
I don't think that's necessarily the best approach though. I would use the events in the navigation lifecycle and set up a handler for $ionicView.loaded instead. You can find details about the event for ion-view in the doc under the section: View LifeCycle and Events.
Related
I'm using AngularJS for my hybrid Ionic app.
My controller:
.controller('SubmitCtrl', function($scope) {
console.log("this just work for only refreshing the page!);
});
Only for each refreshing the page, console.log works fine, but when I switch to other states, and came back to submit state (without refreshing the page), console.log doesn't work.
Any idea?
it is bcoz Ionic cache your page.
Try this
<ion-view cache-view="false" view-title="My Title!">
...
</ion-view>
or,
$stateProvider.state('myState', {
cache: false,
url : '/myUrl',
templateUrl : 'my-template.html'
})
Source: http://ionicframework.com/docs/api/directive/ionNavView/
Though #Ved has answered this question perfectly, disable ionic view cache is not a graceful resolution. If you just want some parts of a page controller to be executed whenever you enter this page, maybe you should make use of ionic view lifecycle:
.controller('SubmitCtrl', function($scope) {
$scope.$on('$ionicView.beforeEnter', function() {
//code in this block will be executed every time before you enter in
console.log("this just work for only refreshing the page!);
});
});
More information about ionic view lifecycle, please refer http://www.gajotres.net/understanding-ionic-view-lifecycle/ and http://ionicframework.com/docs/api/directive/ionView/. Hope this will help, regards!
I have angularjs route with the following definition:
moduleA.config(function($routeProvider){
$routeProvider.
when('/A',{templateUrl:'A.jsp'}).
when('/B',{templateUrl:'B.jsp'}).
when('/C',{templateUrl:'C.jsp'}).
otherwise({
redirectTo: '/',
templateUrl: 'A.jsp'
});
});
Now, let say I click on something and it is redirected to #/C/ view. After refreshing the page, it is redirecting to view C and not to the default view.
I have to show default page after every page refresh happens.
I thought of changing the url to base url while refreshing the page, so that it can be redirected to default page. I am looking for better alternative for this through Angularjs way.
Thanks in advance.
Try this:
In the app.run() block inject 'window' and $location dependency and add:
window.onbeforeunload = function () {
$location.path('/');
};
Like #maurycy commented, If you want user to go to default page anytime a user he's comming to your application, you don't need the event.
just:
$rootScope.$on('$routeChangeStart', function (event, next, current) {
if (!current) {
$location.path('/');
}
});
in your app.run() function.
It should work
I have a webview template which loads data from a link. So, if I have to load a separate webview I use the same template and controller and change the link. It works fine for most cases. However, if I try to load a different webview from the current one it does not work. The reason is that the controller is not triggered again as we are loading the same view. I tried navigating a different page and then moving to webview template, however the result is the same the controller is not initialised. How can I trigger the controller or have the controller reload?
I tried setting cache to false globally and setting reload to true however it still does not reload the controller.
Here is how my code looks
.state('webView', {
url: '/webView',
cache: false,
templateUrl: 'templates/webView.html',
controller: 'WebViewCtrl',
reload: true
});
I have also set
$ionicConfigProvider.views.maxCache(0);
However, my controller still refuses to reload. Any ideas on what am missing?
Finally ended up using state transition mentioned in this link - https://github.com/angular-ui/ui-router/issues/582.
$state.transitionTo($state.current, $stateParams, { reload: true, inherit: false, notify: true });
This did the trick for me and reloaded my view and the controller.
I had a problem previously where I wanted to prevent the page from refreshing when programmatically updating the URL.
I have a "home" view, e.g: /books and I have specific views: e.g: /books/123
The home page has a couple of side panels and a main panel with the list of books.
When clicking on a book, I only want the main panel to update, leaving the rest of the page as it is, but I DO want to update the URL to reflect the book that is loaded. All books should be directly linkable, and so the URL reflects this direct link. I update the URL by setting $location.path() when a specific book is loaded, and I use reloadOnSearch:false in my ui-router state to prevent the refresh.
My routes are set up as follows:
.state('books', {
url: '/books',
title: 'Books',
templateUrl: CONFIG.static_url + '/html/book.html',
controller: 'BookCtrl'
})
.state('book', {
url: '/books/:itemId',
title: 'Books',
templateUrl: CONFIG.static_url + '/html/book.html',
controller: 'BookCtrl',
reloadOnSearch: false
})
This works fine, but it has two problems.
1) When transitioning from the home "Books" page, to a specific book, the page IS refreshed. When transitioning from one specific book to another, the model updates without refreshing the page (which is the desired behaviour).
2) When using the browser back/forward controls, the change in URL is not reflected in the model and so the view doesn't update. However, it does work when transitioning to/from the home page to a specific page.
To fix problem 2, I have set a $watch on $location.path() so if it changes and it doesn't match with the model, I load in the correct item. This appears to work fine.
However, problem 1 remains. How can I seamlessly transition from the Home page, to a specific view, without the whole page refreshing while also retaining the browser back/forward functionality? I can probably continue to use the $watch functionality to update based on the URL, but I can't seem to get it to load without the page refresh.
Make book a child of books and change its URL just to /:itemId.
Do not manually set $location.path(), as this will force a refresh. Redirect between states using ui-sref directive or $state.go() function.
Try something like this:
.state('books', {
url: '/books',
// ... (template should contain <div ui-view></div> where sub-state content will be rendered)
})
.state('books.book', {
url: '/:itemId',
// ... (template and controller just for this sub-state; will get rendered into super-state's ui-view)
})
and link like this:
<a ui-sref="books.book({itemId:123})">Book 123</a>
You need to make the book as a child state of the books. By using that you achieve the required behavior as the book html will already be available for the route. I hope that will work.
For example, I want this change in navigation to reload the state:
#/detail/1
#/detail/2
But I do not want this navigation to reload the state:
#/detail/1?search=blah
#/detail/1?search=huzzah
According to the ui-router documentation, setting reloadOnSearch: false should accomplish this, but try the plunk below. When reloadOnSearch === false, changing the path parameter doesn't reload the state even though the documentation says it should.
Plunkr: http://run.plnkr.co/ZPy9uabYlkMilwdS/#/param
I've created a plunker, demonstrating that ui-router feature reloadOnSearch is working as documented here:
reloadOnSearch:
Boolean (default true). If false will not retrigger the same state just because a search/query parameter has changed. Useful for when you'd like to modify $location.search() without triggering a reload.
So, what this says, that if we do have state like this
.state('index.detail', {
url: '/detail/:id',
reloadOnSearch : false,
...
})
navigating to the
ui-sref="index.detail({id:1})"
will load this state, while navigating to
ui-sref="index.detail({id:any-other-id})"
will do nothing. But! If we would introduce new (e.g. sibling) state defined like this:
.state('index.other', {
url: '/other/:id',
reloadOnSearch : false,
...
})
navigating to below sequence will always re-trigger state reload, not because the param change, but because the state change
<a href="#/index/detail/1" ...
<a href="#/index/other/1" ... // will relaod
<a href="#/index/detail/2" ... // because the state
<a href="#/index/other/2" ... // is changing
See that all in action here...
This is a bug in UI-Router that was fixed in release 0.2.15:
https://github.com/angular-ui/ui-router/releases
Upgrading to the latest will fix the issue