Force reload route/state on link click
Asked Answered
W

4

5

Currently I'm doing something like this

link.on('click', function () {
    if (link.attr('href') !== $route.current.originalPath)
        return;
    $route.reload();
});

I'm not aware of side effects but I guess there can be some.

Is there more straightforward way to handle this in ngRoute, e.g. through $location?

What is the way to do the same thing in UI Router when the app will be updated to use it?

Warranty answered 30/10, 2015 at 18:34 Comment(0)
M
1

Your code could get tranformed to below change $route.reload() to $state.reload()

Code

link.on('click', function () {
    if (link.attr('href') !== $route.current.originalPath)
        return;
    //though this will not reload the controller content
    $state.reload(); //will force to reload state..
    $scope.$apply(); //needed here to tell angular js to run digest cycle.
});

From git-hub issue it seems like $state.reload() reload the state but controller doesn't get re-instantiate. For that you need to use below code instead of $state.reload()

$state.transitionTo('tab.locations', $state.$current.params, { 
  reload: true, inherit: true, notify: true 
});
Marguerite answered 3/11, 2015 at 19:3 Comment(2)
That's a good point, I believe I did $apply() in my original code, and sure, it is necessary here.Warranty
@estus yes..thats neccesary..any angular code called externally(out of angular context) need to tell angular to updated those changes(to reflect the bindings.)Marguerite
P
8

With UI-Router we have a set of options, and one of them is {reload: true}

go(to, params, options)

  • location - {boolean=true|string=} - If true will update the url in the location bar, if false will not. If string, must be "replace", which will update url and also replace last history record.
  • inherit - {boolean=true}, If true will inherit url parameters from current url.
  • relative - {object=$state.$current}, When transitioning with relative path (e.g '^'), defines which state to be relative from.
  • notify - {boolean=true}, If true will broadcast $stateChangeStart and $stateChangeSuccess events.
  • reload (v0.2.5) - {boolean=false}, If true will force transition even if the state or params have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd use this when you want to force a reload when everything is the same, including search params.

So we can force state reload with:

$state.go("stateName", stateParams, {reload: true});
Plaintiff answered 30/10, 2015 at 18:36 Comment(1)
Didn't have a chance to embrace 0.2.5, that's beautiful.Warranty
M
1

Your code could get tranformed to below change $route.reload() to $state.reload()

Code

link.on('click', function () {
    if (link.attr('href') !== $route.current.originalPath)
        return;
    //though this will not reload the controller content
    $state.reload(); //will force to reload state..
    $scope.$apply(); //needed here to tell angular js to run digest cycle.
});

From git-hub issue it seems like $state.reload() reload the state but controller doesn't get re-instantiate. For that you need to use below code instead of $state.reload()

$state.transitionTo('tab.locations', $state.$current.params, { 
  reload: true, inherit: true, notify: true 
});
Marguerite answered 3/11, 2015 at 19:3 Comment(2)
That's a good point, I believe I did $apply() in my original code, and sure, it is necessary here.Warranty
@estus yes..thats neccesary..any angular code called externally(out of angular context) need to tell angular to updated those changes(to reflect the bindings.)Marguerite
M
1

I found this to be the shortest way with UI-router :

$state.go($state.current, {}, {reload: true});

or you can do this :

$state.transitionTo($state.current, $stateParams, {
       reload: true,
       inherit: false,
       notify: true
     });
Misericord answered 4/11, 2015 at 11:51 Comment(0)
M
0

If you are using Ui.Router:

link.on('click', function (event) {
    if (link.attr('href') !== $route.current.originalPath)
        return;
  
    event.preventDefault();
    
    return $scope.$apply(function() {
      return $state.reload(); // $state.go($state.current.name, $stateParams, { inherit: false, reload: true, notify: true });
    });
});

If you are using the simply ngRoute, you must to remove your the currentTemplate from templateCache and the return $route.reload() in a $timout!

Marenmarena answered 5/11, 2015 at 15:14 Comment(4)
Regarding UI Router part, I don't see how this supplements existing answers. And for ngRoute some explanation may be beneficial, I'm not sure that ruining template cache can help.Warranty
In your example you don't exec event.preventDefault, required if the event is attached on a link object. For ngRoute, instead, this is a known issue... so, if you want to force the route reloading you have to remove the current-route-template from templateCacheMarenmarena
e.preventDefault is done by $location, that's why it isn't in original snippet. I'm not sure that messing with templateCache will change something, please, provide a plunker if it is true.Warranty
try in your application, you can vote me down if doesn't work!Marenmarena

© 2022 - 2024 — McMap. All rights reserved.