shared controller between scopes

1,186 views
Skip to first unread message

Tobias Bosch

unread,
Mar 22, 2012, 1:42:46 PM3/22/12
to ang...@googlegroups.com
Hi,
I know that the communication between controllers has been discussed some times. And one solution was to use a common parent controller which stores the common data, or use a service to keep the shared state.

In the jquery-mobile-angular-adapter we created another solution: a shared controller. This is a controller which gets an own scope, and is injected into the current scope using a variable as prefix.

Syntax: <ANY ngm-shared-controller="name1:Controller1,name2:Controller2, ...">
Access to those controller in the page: {{name1.ANY}}, ...

Reasons behind this: 
a) In mobile projects, business logic for one use case is very often spread across multiple mobile pages. Creating an own controller for every page would be a lot technical code, and we would need to pass a lot data between those simple page controllers.
b) Using a common parent controller is also no good solution for projects with jquery mobile:
Every page is at the same dom element depth, usually directly under the "body"-tag. So we can only create on common parent controller for all pages. However, this would put different aspects of the application in a single file, which is not good from a maintenance point of view.
c) Using a service to hold the common data is also not working well, as we then still need a controller for every page, right?

I posted this to share this code with you and to get some feedback from the community about this, so: 
What do you think about this solution for the problem mentioned above?

Tobias

Igor Minar

unread,
Mar 22, 2012, 2:23:05 PM3/22/12
to ang...@googlegroups.com
On Thu, Mar 22, 2012 at 10:42 AM, Tobias Bosch <tbosc...@googlemail.com> wrote:
Hi,
I know that the communication between controllers has been discussed some times. And one solution was to use a common parent controller which stores the common data, or use a service to keep the shared state.

In the jquery-mobile-angular-adapter we created another solution: a shared controller. This is a controller which gets an own scope, and is injected into the current scope using a variable as prefix.

I see that you are creating scopes off of the root scope, but you never destroy them. what is the garbage collection strategy here? I think I smell a memory leak here.

 
Syntax: <ANY ngm-shared-controller="name1:Controller1,name2:Controller2, ...">
Access to those controller in the page: {{name1.ANY}}, ...

Reasons behind this: 
a) In mobile projects, business logic for one use case is very often spread across multiple mobile pages. Creating an own controller for every page would be a lot technical code, and we would need to pass a lot data between those simple page controllers.
b) Using a common parent controller is also no good solution for projects with jquery mobile:
Every page is at the same dom element depth, usually directly under the "body"-tag. So we can only create on common parent controller for all pages. However, this would put different aspects of the application in a single file, which is not good from a maintenance point of view.

do you use ng-view/$route?
 
c) Using a service to hold the common data is also not working well, as we then still need a controller for every page, right?

why can't you reuse a controller for multiple pages?

/i

Tobias Bosch

unread,
Mar 22, 2012, 3:52:21 PM3/22/12
to ang...@googlegroups.com
Hi,
thanks for your ideas and your reply!

We can't use ng-view/$route, as we want to keep the nice transitions that jquery-mobile does between the pages. For this to work both pages (the old and the new one) need to be in the DOM at the same time. Also, recompiling the pages when we change from one page to the next could be a performance problem.

Your idea with the same controller multiple times could work:
To share data between the pages, this would require a service for every use case that holds the data (as the controllers are reinstantiated for every page). 
Then I could create a single controller that is used on every page, but has no state at all. The controller then could just put an object of the service into the scope (or maybe the whole service?). 
Something like this: http://jsfiddle.net/8Z22S/2/
But then the controller would be without a real responsibility. This could be stripped down further by providing a directive that just publishes a service into a scope,
like so:

This could be an alternative to the ngm-shared-controller. However, this would remove controllers at all and just use services!

To the memory leak: We could get a memory leak if we would dynamically add shared controllers. However, if we used a service for every use case, this would be same problem, as services are singletons and therefore also never get freed. 

Tobias

Tobias Bosch

unread,
Mar 23, 2012, 6:17:00 AM3/23/12
to ang...@googlegroups.com
Hi,
thanks again for the hint with the memory leak.
So here is a version of the shared controller that does reference counting and frees memory if no more used.

Tobias

Igor Minar

unread,
Mar 26, 2012, 2:03:01 PM3/26/12
to ang...@googlegroups.com
That looks better!

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To view this discussion on the web visit https://groups.google.com/d/msg/angular/-/7bbsjlSmEs0J.

To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/angular?hl=en.

jaume...@gmail.com

unread,
Dec 10, 2012, 11:52:47 AM12/10/12
to ang...@googlegroups.com
Hi Tobias,

I am new with your adapter but for the tests I have done, it seems that the different pages must be under the same controller so I can navigate through them.
Is that right? Should I use a shared controller?

I am developing a pretty complex web app and I want each page to have a different controller.

Thanks!

Tobias Bosch

unread,
Dec 11, 2012, 3:05:46 AM12/11/12
to ang...@googlegroups.com, jaume...@gmail.com
Hello jaumeavila,
in the adapter, navigation is independent of controllers.. 
So you can use an own `ng-controller` attribute with an own controller on every page. If you want to share data between the pages, you can either use a root controller (e.g. put the `ng-controller` attribute at the `<body>` tag), or you can use a shared-controller, as documented in the Readme.md of the adapter.

Tobias

hanne...@gmail.com

unread,
Mar 14, 2014, 9:02:35 PM3/14/14
to ang...@googlegroups.com, jaume...@gmail.com, tbosc...@googlemail.com
Hey Tobias, 

I am very new with angularjs and jquery mobile, but i want to use it for a project in university.
Is it possible to use a shared controller for all pages and in addition to that a controller for every page? 
In your last post you wrote "you can either use a root controller (e.g. put the `ng-controller` attribute at the `<body>` tag), or you can use a shared-controller" so i just want to know if it is possible to use both or not.

Thanks,
Hanne

Reply all
Reply to author
Forward
0 new messages