I'm using angular-ui's router (v0.2.0) in a project and we're trying to reload a view. I've tried $state.transitionTo and also $state.go, but neither seem to do anything. Would anyone know how to do a reload?
Thank you!
The 3rd parameter of $state.go takes an options object which has a reload property, so doing something like
$state.go('resources', {start: $stateParams.start}, {reload:true});
Should do the trick - on the latest version I can confirm it works.
If you are using v 0.2.5
This is working . $state.reload()
Reference Link
In Angular UI route v0.2.5, there is a third parameter reload
$state.transitionTo(to, toParams [, options])
$state.go(to, toParams [, options])
Third parameter is optional.
$state.go('contacts', {sort: 'name' }, { reload: true });
If you are going from state A to state A again, the internals of the angular-ui would forbid it from reloading the state. You'd have to go to a different state to have a reload. That is to avoid clicking many times on the same link issuing a reload.
You can try switching to the same state, but with slightly different params, if you are that desperate to reissue a reload. But in my point of view, if you are in the same state, a reload shouldn't happen.
There is already also a similar question on SO:
$route.reload() does not work with ui-router
If you are ok with using grunt and building yourself there is a new $state.reload() feature. Or you can wait until v0.3 coming soonish.
Comment on similar question Reloading current state - refresh data by SimplGy:
Probably worth noting that none of these [edit: meaning $state.transitionTo('state'), $state.reload() or $state.go($state.current, {}, {reload: true})] actually reload the page as
well. If you want to reload the state AND the page, there is no
ui-router method for it I think. Do window.location.reload(true)
Another comment by edhedges improved this one by mentioning the use of
$window.location.reload()
Which works and I recommend using for the reloading a ui-view.
Related
I'm using ui-router 1.0b3 with angular 1.5.x. Also using html5Mode(true). The hash's are not being used for the paths, they are just for the specific page it goes to.
I want to be able to go to
http://example.com/app/page#tab3
route name: app.page
Then navigate to another page, say route name: app.another, it will take me to the page, but the # stays. I don't want the # state to follow the navigation. Both pages need the same "app" parent. If I go to another it should not go to "http://example.com/app/another#tab3" which is what is is doing.
It did not do this on ui-router 0.3.1
I tried removing the hash during the transition:
$transitions.onBefore({exiting: 'app.**'}, function(trans) {
trans.params("to")["#"] = null;
$location.hash("");
});
but that doesn't work at all.
Help? I think this might be a bug, but I can't figure out a fix.
https://github.com/angular-ui/ui-router/issues/3245
I have the same problem. I found solution to the problem of ui-router developers.
You can clear out the hash by clearing out the parameter (parameter named '#').
In templates:
<a ui-sref="app.tasks({'#': null})">text</a>
In javascript code:
$state.go('app.tasks', {'#': null});
P.S. I use angular-ui-router, version is 1.0.0-beta.3
More information here:
https://github.com/angular-ui/ui-router/issues/3017
I am new to mobile application development with Ionic. On login and logout I need to reload the page, in order to refresh the data, however, $state.go('mainPage') takes the user back to the view without reloading - the controller behind it is never invoked.
Is there a way to clear history and reload the state in Ionic?
Welcome to the framework! Actually the routing in Ionic is powered by ui-router. You should probably check out this previous SO question to find a couple of different ways to accomplish this.
If you just want to reload the state you can use:
$state.go($state.current, {}, {reload: true});
If you actually want to reload the page (as in, you want to re-bootstrap everything) then you can use:
$window.location.reload(true)
Good luck!
I found that JimTheDev's answer only worked when the state definition had cache:false set. With the view cached, you can do $ionicHistory.clearCache() and then $state.go('app.fooDestinationView') if you're navigating from one state to the one that is cached but needs refreshing.
See my answer here as it requires a simple change to Ionic and I created a pull request: https://stackoverflow.com/a/30224972/756177
The correct answer:
$window.location.reload(true);
I have found a solution which helped me to get it done. Setting cache-view="false" on ion-view tag resolved my problem.
<ion-view cache-view="false" view-title="My Title!">
....
</ion-view>
Reload the page isn't the best approach.
you can handle state change events for reload data without reload the view itself.
read about ionicView life-cycle here:
http://blog.ionic.io/navigating-the-changes/
and handle the event beforeEnter for data reload.
$scope.$on('$ionicView.beforeEnter', function(){
// Any thing you can think of
});
In my case I need to clear just the view and restart the controller. I could get my intention with this snippet:
$ionicHistory.clearCache([$state.current.name]).then(function() {
$state.reload();
});
The cache still working and seems that just the view is cleared.
ionic --version says 1.7.5.
None of the solutions mentioned above worked for a hostname that is different from localhost!
I had to add notify: false to the list of options that I pass to $state.go, to avoid calling Angular change listeners, before $window.location.reload call gets called. Final code looks like:
$state.go('home', {}, {reload: true, notify: false});
>>> EDIT - $timeout might be necessary depending on your browser >>>
$timeout(function () {
$window.location.reload(true);
}, 100);
<<< END OF EDIT <<<
More about this on ui-router reference.
I was trying to do refresh page using angularjs when i saw websites i got confused but no code was working for the code then i got solution for reloading page using
$state.go('path',null,{reload:true});
use this in a function this will work.
I needed to reload the state to make scrollbars work. They did not work when coming through another state - 'registration'. If the app was force closed after registration and opened again, i.e. it went directly to 'home' state, the scrollbars worked. None of the above solutions worked.
When after registration, I replaced:
$state.go("home");
with
window.location = "index.html";
The app reloaded, and the scrollbars worked.
The controller is called only once, and you SHOULD preserve this logic model, what I usually do is:
I create a method $scope.reload(params)
At the beginning of this method I call $ionicLoading.show({template:..}) to show my custom spinner
When may reload process is finished, I can call $ionicLoading.hide() as a callback
Finally, Inside the button REFRESH, I add ng-click = "reload(params)"
The only downside of this solution is that you lose the ionic navigation history system
Hope this helps!
If you want to reload after view change you need to
$state.reload('state',{reload:true});
If you want to make that view the new "root", you can tell ionic that the next view it's gonna be the root
$ionicHistory.nextViewOptions({ historyRoot: true });
$state.go('app.xxx');
return;
If you want to make your controllers reload after each view change
app.config(function ($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
$ionicConfigProvider.views.maxCache(0);
.state(url: '/url', controller: Ctl, templateUrl: 'template.html', cache: false)
cache: false ==> solved my problem !
As pointed out by #ezain reload controllers only when its necessary. Another cleaner way of updating data when changing states rather than reloading the controller is using broadcast events and listening to such events in controllers that need to update data on views.
Example: in your login/logout functions you can do something like so:
$scope.login = function(){
//After login logic then send a broadcast
$rootScope.$broadcast("user-logged-in");
$state.go("mainPage");
};
$scope.logout = function(){
//After logout logic then send a broadcast
$rootScope.$broadcast("user-logged-out");
$state.go("mainPage");
};
Now in your mainPage controller trigger the changes in the view by using the $on function to listen to broadcast within the mainPage Controller like so:
$scope.$on("user-logged-in", function(){
//update mainPage view data here eg. $scope.username = 'John';
});
$scope.$on("user-logged-out", function(){
//update mainPage view data here eg. $scope.username = '';
});
I tried many methods, but found this method is absolutely correct:
$window.location.reload();
Hope this help others stuck for days like me with version: angular 1.5.5, ionic 1.2.4, angular-ui-router 1.0.0
There doesn't appear to be a built-in way to update the url without running all of the other processes, e.g. invoking controllers.
The option "reload", only works with $location.search()
Is there a method, or approach to achieve
How may I achieve something similar to:
$state.go('stateName', params, {justChangeTheUrl: true})
With Angular UI-Router?
If you just want to change the url without having that change processed by ui-router then you can use the following perfectly acceptable hack (coffeescript):
scopeOff = $scope.$on '$stateChangeStart', (e) ->
e.preventDefault()
scopeOff()
$location.path 'just/change/the/url'
Notes
Normally making a change to the browser url via $location.path() would trigger ui-router to begin its processing. This processing starts with the ui-router specific event called $stateChangeStart.
In the code above, however, you are catching and, via e.preventDefault(), throwing away this initial call to $stateChangeStart event and so preventing ui-router from processing the url change.
The watch on the $stateChangeStart event is 'single use', that is the code automatically detaches itself from the event after one run (this is what the call to scopeOff() is doing).
The net effect is to change the url in the browser without triggering ui-router processing and to only apply this restriction to the one url you have just changed. Neat, but not as neat as the new deferIntercept feature that will be with us soon.
Define state parameter in url
$stateProvider.state('stateName', {
url: '/state/path?reload'
});
But be carefull, every $location.search() change on reload param will trigger $stateChangeStart event, and your controller will be recreated
I'm building a dashboard system in AngularJS and I'm running into an issue with setting the url via $location.path
In our dashboard, we have a bunch of widgets. Each shows a larger maximized view when you click on it. We are trying to setup deep linking to allow users to link to a dashboard with a widget maximized.
Currently, we have 2 routes that look like /dashboard/:dashboardId and /dashboard/:dashboardId/:maximizedWidgetId
When a user maximizes a widget, we update the url using $location.path, but this is causing the view to re-render. Since we have all of the data, we don't want to reload the whole view, we just want to update the URL. Is there a way to set the url without causing the view to re-render?
HTML5Mode is set to true.
In fact, a view will be rendered everytime you change a url. Thats how $routeProvider works in Angular but you can pass maximizeWidgetId as a querystring which does not re-render a view.
App.config(function($routeProvider) {
$routeProvider.when('/dashboard/:dashboardId', {reloadOnSearch: false});
});
When you click a widget to maximize:
Maximum This Widget
or
$location.search('maximizeWidgetId', 1);
The URL in addressbar would change to http://app.com/dashboard/1?maximizeWidgetId=1
You can even watch when search changes in the URL (from one widget to another)
$scope.$on('$routeUpdate', function(scope, next, current) {
// Minimize the current widget and maximize the new one
});
You can set the reloadOnSearch property of $routeProvider to false.
Possible duplicate question : Can you change a path without reloading the controller in AngularJS?
Regards
For those who need change full path() without controllers reload
Here is plugin: https://github.com/anglibs/angular-location-update
Usage:
$location.update_path('/notes/1');
I realize this is an old question, but since it took me a good day and a half to find the answer, so here goes.
You do not need to convert your path into query strings if you use angular-ui-router.
Currently, due to what may be considered as a bug, setting reloadOnSearch: false on a state will result in being able to change the route without reloading the view. The GitHub user lmessinger was even kind enough to provide a demo of it. You can find the link from his comment linked above.
Basically all you need to do is:
Use ui-router instead of ngRoute
In your states, declare the ones you wish with reloadOnSearch: false
In my app, I have an category listing view, from which you can get to another category using a state like this:
$stateProvider.state('articles.list', {
url: '{categorySlug}',
templateUrl: 'partials/article-list.html',
controller: 'ArticleListCtrl',
reloadOnSearch: false
});
That's it. Hope this helps!
We're using Angular UI Router instead of built-in routes for a similar scenario. It doesn't seem to re-instantiate the controller and re-render the entire view.
How I've implemented it:
(my solution mostly for cases when you need to change whole route, not sub-parts)
I have page with menu (menuPage) and data should not be cleaned on navigation (there is a lot of inputs on each page and user will be very very unhappy if data will disappear accidentally).
turn off $routeProvider
in mainPage controller add two divs with custom directive attribute - each directive contains only 'templateUrl' and 'scope: true'
<div ng-show="tab=='tab_name'" data-tab_name-page></div>
mainPage controller contains lines to simulate routing:
if (!$scope.tab && $location.path()) {
$scope.tab = $location.path().substr(1);
}
$scope.setTab = function(tab) {
$scope.tab = tab;
$location.path('/'+tab);
};
That's all. Little bit ugly to have separate directive for each page, but usage of dynamic templateUrl (as function) in directive provokes re-rendering of page (and loosing data of inputs).
If I understood your question right, you want to,
Maximize the widget when the user is on /dashboard/:dashboardId and he maximizes the widget.
You want the user to have the ability to come back to /dashboard/:dashboardId/:maximizedWidgetId and still see the widget maximized.
You can configure only the first route in the routerConfig and use RouteParams to identify if the maximized widget is passed in the params in the controller of this configured route and maximize the one passed as the param. If the user is maximizing it the first time, share the url to this maximized view with the maximizedWidgetId on the UI.
As long as you use $location(which is just a wrapper over native location object) to update the path it will refresh the view.
I have an idea to use
window.history.replaceState('Object', 'Title', '/new-url');
If you do this and a digest cycle happens it will completely mangle things up. However if you set it back to the correct url that angular expects it's ok. So in theory you could store the correct url that angular expects and reset it just before you know a digest fires.
I've not tested this though.
Below code will let you change url without redirection such as: http://localhost/#/691?foo?bar?blabla
for(var i=0;i<=1000;i++) $routeProvider.when('/'+i, {templateUrl: "tabPages/"+i+".html",reloadOnSearch: false});
But when you change to http://localhost/#/692, you will be redirected.
I'm currently trying to figure out how to change the route parameters without reloading the entire page. For example, if I start at
http://www.example.com/#/page
but update a name to be 'George', to change the route to be:
http://www.example.com/#/page/george
If I already had http://www.example.com/#/page/:name routed.
Without reloading the location. Can one just set $routeParams.name = "George" ?
Edit:
Alternatively, is there a way to update http://www.example.com/#/page?name=George without reloading or resetting the page?
Ok, after a lot of searching. I answered my own question.
I've discovered finding anything on the angular documentation is incredibly impossible, but sometimes, once it's found, it changes how you were thinking about your problem.
I began here: http://docs.angularjs.org/api/ng.$location
Which took me here: http://docs.angularjs.org/guide/dev_guide.services.$location
Which took me to this question: AngularJS Paging with $location.path but no ngView reload
What I ended up doing:
I added $location.search({name: 'George'}); To where I wanted to change the name (A $scope.$watch).
However, this will still reload the page, unless you do what is in that bottom StackOverflow link and add a parameter to the object you pass into $routeProvider.when. In my case, it looked like: $routeProvider.when('/page', {controller: 'MyCtrl', templateUrl:'path/to/template', reloadOnSearch:false}).
I hope this saves someone else a headache.
I actually found a solution that I find a little more elegant for my application.
The $locationChangeSuccess event is a bit of a brute force approach, but I found that checking the path allows us to avoid page reloads when the route path template is unchanged, but reloads the page when switching to a different route template:
var lastRoute = $route.current;
$scope.$on('$locationChangeSuccess', function (event) {
if (lastRoute.$$route.originalPath === $route.current.$$route.originalPath) {
$route.current = lastRoute;
}
});
Adding that code to a particular controller makes the reloading more intelligent.
You can change the display of the page using ng-show and ng-hide, these transitions won't reload the page. But I think the problem you're trying to solve is you want to be able to bookmark the page, be able to press refresh and get the page you want.
I'd suggest implementing angular ui-router Which is great for switching between states without reloading the page. The only downfall is you have to change all your routes.
Check it out here theres a great demo.