0

Ok, I have a reasonable amount of experience with angular and ui-router, but I'm running into an issue when it comes to the architecture of my app. I have some states like:

main.module.js

.state('main', {
    abstract: true,
    controller: 'MainCtrl',
    template: '<div ui-view />'
}).state('main.clients', {
    url: '/clients/:id',
    views: {
        list: {controller: 'ClientListCtrl', templateUrl: 'client-list.html'},
        detail: {controller: 'ClientDetailCtrl', templateUrl: 'client-detail.html'}
    }
}.state('main.services', {
    url: '/services/:id',
    views: {
        list: {...},
        detail: {...}
    }
}

main.html

<div>
    <div ui-view='list'></div>
    <div ui-view='detail'></div>
</div>

client-list.html

<ul>
    <li data-ng-click='$state.go('main.clients({id: client.id})' 
        data-ng-repeat='client in clients'>
        {{client.name}}
    </li>
</ul>

This all seems to work fine, and views are populated as I would expect. My main question is, when I'm in the main.clients state and a user clicks on the client name, the $state.go(...) fires, it re-initializes the ClientListCtrl and ClientDetailCtrl, even though the state didn't actually change (well, the :id portion of the url did) .

Am I misusing multiple views? Would a change of architecture be advisable? Just trying to wrap my head around how to structure this in the most efficient way, and the controller re-initialization doesn't seem like it's necessary in this case, but I'm probably missing something. Thanks!

Greg
  • 6,453
  • 9
  • 45
  • 61
  • What do you mean by reinitialization? How do you define that? Actually you are going to different URL and all data may be different there. So scope have to be updated. To me it is normal behaviour. – Sergey Romanov Oct 01 '14 at 01:49
  • You might be right. The use case is where I have a list of items on the left that update that "detail" area on the right when clicked on. So I have a ClientListCtrl and ClientDetailCtrl. The ClientListCtrl for instance is re-initializing when I go to a new main.client state (where the :id changed). I say re-initializing because the controller for ClientListCtrl is running each time, even though it doesn't need to be updated. – Greg Oct 01 '14 at 02:04
  • But ungular do not know that only one of your controllers in the list needs to be updated and other stays the same. If this is the case, may be you need to move that controller to parent state. Also give paranet satte an URL and make it not abstract. Then parent will initialize one controler and child another one and only one everytime you change the state. – Sergey Romanov Oct 01 '14 at 02:41

1 Answers1

1

Reload on state or its param change is what we want (I would say) in 99% cases. New params would mean different list/detail.

But there is a setting:

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.

I created an example here showing how to turn of the reload on search.

  • State changes do trigger reload,
  • params changes do not

snippet:

  .state('index', {
      url: '/index/:area',
      ...
    })
    .state('index.detail', {
      url: '/detail/:id',
      reloadOnSearch : false,
      ...

Would say, that the default behaviour is what we need, even with resolvers. But ... check that change in action here

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335