25

When a state is clicked at first, the div that owns the "ui-view" attribute is replaced with the "template" of that state. However, when I click the same state again, its controller does not reloaded. How can I make this controller to load again?

For example, suppose I have the following navigation menu:

<nav> 
    <a ui-sref="state1">State 1</a>
    <a ui-sref="state2">State 2</a>
</nav>

My "ui-view" content is as follows:

<div ui-view></div>

My states are described as below. When I click the "State1" on the navigation menu, I expect to observe the text "Ctrl 1 loaded" on the developer console. If it's first time, then I observe that text. However, when I re-click the same link, the controller is not loaded again that is I couldn't see the text "Ctrl 1 loaded" displayed on the console twice.

myApp.config(function ($stateProvider, $urlRouterProvider){
    $stateProvider.state("state1", {
        url: "#",
        template: "<p>State 1</p>",
        controller: "Ctrl1"
      }).state("state2", {
        url: "#",
        template: "<p>State 2</p>",
        controller: "Ctrl2"
      });
});

Why? Do you have any idea?

Here is the JSFiddle of this question.

ankakusu
  • 1,738
  • 8
  • 26
  • 37

4 Answers4

86

Like Philipp said, it is because this is the default behavior of ui-router, BUT if you would like to reload your controller each time you click on your link, you can actually use the ui-sref-opts attribute to force it, like this:

<a ui-sref="state1" ui-sref-opts="{reload: true}">State 1</a>

Found this tip here:

https://github.com/angular-ui/ui-router/commit/91a568454cc600aa4f34dedc8a80c9be1130b1c5

Hope it could help

schankam
  • 10,778
  • 2
  • 15
  • 26
14

Alternative syntax to go to a different view it would be

<a ui-sref="state1({reload: true})">State 1</a>

On the controller it would look like this.

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

Note: The second parameter of $state.go is $stateParams.

Sean Perkins
  • 541
  • 3
  • 10
Rick
  • 12,606
  • 2
  • 43
  • 41
  • 3
    How random, for me its the other way around, `ui-sref-opts` works but passing `reload: true` into the state in `ui-sref` doesn't! Anyone else with this problem I recommend trying either. – teaforchris Dec 14 '15 at 15:20
  • What version of angular are you using? – Rick Dec 14 '15 at 20:39
3

Because that's how ui-router is designed.

The controller is only loaded when it isn't in the same state. ui-router will not rerun a controller, and not reevaluate a view template. Even when you use the same controller on multiple states and switch between those, the controller will not rerun.

If you want to run functionality when the a view changes you could listen for events, or even put an ng-click on your a element.

Philipp Gayret
  • 4,870
  • 1
  • 28
  • 34
  • Thank you for the reply. How can call the function again with ng-click ? – ankakusu Aug 06 '14 at 10:08
  • @ankakusu You'd probably have to set up a listener in the controller and emit an event from the `ng-click`, more [here](http://stackoverflow.com/questions/14502006/scope-emit-and-on-angularjs). – Philipp Gayret Aug 06 '14 at 10:27
  • ng-click event is supressed as well. I binded an ng-click event to State 1. Even though I click on the item, ng-click event is not fired. You can check from [this CodePen](http://codepen.io/ya/pen/Kantr?editors=101). – ankakusu Aug 06 '14 at 14:39
  • @ankakusu `Ctrl1` controls only the elements below `ui-view`, `click` defined on the scope of `Ctrl1` will only get triggered if you call if from within the view. [Here's a sample with a navbar controller](http://codepen.io/anon/pen/awGJL). If you use this, with messaging on the scope with `$emit` ( on click ) and `$on` ( in the `Ctrl1` ), you can receive the event, on `Ctrl1`'s scope. – Philipp Gayret Aug 06 '14 at 19:24
  • Create New Home it's not working properly. Please suggest me, what should we can change it... – Shivendra Prakash Shukla Aug 17 '18 at 04:35
1

just use below code

$stateProvider.
  state('myPage', {
    url: '/',
    cache: false // add this line
Ravi Rajindu
  • 380
  • 2
  • 6
  • 23