8

Is it possible to have multiple views [https://github.com/angular-ui/ui-router/issues/494] with a singleton controller?

Use case: I have a ui-view=header and ui-view=content. I change the header depending on the current state to display context relative buttons (ie go back, save, filter, etc.) I want those buttons to call a function in the content controller, but if I do the following it creates two MyController objects. If there's any init functions they get called twice, which in most cases is double the queries to my server.

views:{
  'header':{
    templateURL:'...',
    controller:'MyController'
  },
  'content':{
    templateURL:'...',
    controller:'MyController'
  }
}

Update: Based on @pankajparkar

My current index.html looks like this (simplified for understanding)

<nav ui-view="header"></nav>
<div ui-view="content"></div>

But your suggestion would consist of/REQUIRE subviews

<!--index.html-->
<body ui-view></body>

<!--format.html-->
<nav ui-view="header"></nav>
<div ui-view="content"></div>

With the following controller

state('app', {
  url: '/app',
  controller: 'MyController',
  templateURL: 'format.html', //Targets ui-view in index.html
  views:{
    'header':{
      templateURL:'...', //Targets ui-view="header" in format.html
    },
    'content':{
      templateURL:'...', //Targets ui-view="header" in content.html
    }
  }
});
Yongfeng
  • 666
  • 7
  • 22
Ryan H
  • 547
  • 1
  • 6
  • 18

3 Answers3

2

You basically need to handle this kind of stuff in some sort of provider (typically a service or a factory) those are singletons and then you can inject the singleton into the controller and each instance of the controller will be using the shared/same provider.

If you need help implementing this please share your controller.

Although I do agree with the suggestions in the other answer posted here, you may want to consider putting the functionality in a provider anyhow. In most situations you're best off having most of the functionality and data living in providers and having your controllers just be responsible for passing along the user interactions to trigger the appropriate call in the providers (and it would fix your current problem since they are singletons).

shaunhusain
  • 19,630
  • 4
  • 38
  • 51
  • Comparing both suggestions, this was the most solid response. Although I liked the concept of @pankajparkar, I could not get it working and the more I had to do made it feel like a work around/hack. This method took some work; however, it worked exactly as expected. – Ryan H Apr 22 '15 at 18:05
1

I have it working in this way:

$stateProvider.state("abc",{
   url:'/abc',
    views:{
    '':{
        templateUrl: 'abc.html',
        controller:'MyController' <-- it's also attached to subviews
    },
    'header@abc':{
        templateURL:'...'
    },
    'content@abc':{
       templateURL:'...'
     }
   }

})
Musma
  • 924
  • 9
  • 16
0

You should put that controller outside views option so that it will load only once on the page

$stateProvider.state("abc",{
   url:'/abc',
   templateUrl: 'abc.html',
   controller:'MyController', //<---place it here will load it once
    views:{
    'header':{
        templateURL:'...'
    },
    'content':{
       templateURL:'...'
     }
   }

})
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • 3
    Definitely a good option as well, either this way or having it as a controller for an abstract parent state for some set of states. – shaunhusain Apr 17 '15 at 20:03
  • @shaunhusain yeah..you could do that to..but as per OP question, I gave example for it. – Pankaj Parkar Apr 17 '15 at 20:04
  • 1
    What would theoretically be in templateURL: 'abc.html'? I'm trying this and it doesn't seem to be calling the controller. – Ryan H Apr 17 '15 at 20:25
  • @RyanH theorotically I gave `abc.html` for example purpose,`abc.html` would would be the base page on which you have declared inner `ui-view` – Pankaj Parkar Apr 17 '15 at 20:28
  • basically `abc.html` may contain `` – Pankaj Parkar Apr 17 '15 at 20:44
  • Please see my update if this is what you mean? If so, are you creating issues with a 'parent' controller that will cause ghosting of variables? – Ryan H Apr 17 '15 at 20:58
  • Yes the current changes you made are correct..I dont think so there would any issue related to scope – Pankaj Parkar Apr 17 '15 at 21:52
  • @Anoop.P.A may I know what problem you are facing? – Pankaj Parkar May 16 '16 at 10:25
  • 1
    @Pankaj I'm banging my head on this issue for some days. I tried many ways to get a single controller work on many views. Refer http://stackoverflow.com/questions/33134124/ui-router-multiple-views-single-controller-not-work to see why this will not work. I would be very much happy if this would have worked. Because it would solve my problem in a neat way. :) – Anoop Thiruonam May 16 '16 at 10:34
  • @downvoter please do add comment after downvote, to let answerer know whats the mistake, so that I can improve it further. :) – Pankaj Parkar May 17 '16 at 06:57
  • @Pankaj : same reason as the one pointed by Anoop. This is not working. – Flint May 21 '16 at 16:11