Preserving State Across Views

74 views
Skip to first unread message

Rajesh

unread,
Mar 17, 2014, 1:17:09 AM3/17/14
to ang...@googlegroups.com
We have a fairly complex application (more than 100 views and controllers). Let me explain the problem space with an example. When a user is trying to create a new quotation (View 1), they may not find a product in the list. So they need to go to a different view (View 2) to add a new product, and then continue working on the quotation (View 1). The data entered on the quotation before adding the new product should be retained while returning after adding the new product.

While using a service to share data between these controllers seems to do the job, we have a large number of such use cases, and therefore there will be a large number of services and dependencies to manage. Is it a good practice to use the rootScope for storing and retrieving the state instead?

A similar use case is to retain the filter (search) values on a list view after the user navigates to a different view and comes back.

Thanks!

Robert Paddock

unread,
Mar 17, 2014, 1:25:45 AM3/17/14
to ang...@googlegroups.com
I would consider using local storage if that is an option. Alternatively using a some sort of generic Service for saving states.  You may want to look at Restangular as I'm pretty sure that has some sort of state provider.

Cheers Rob

Luke Kende

unread,
Mar 17, 2014, 1:58:24 AM3/17/14
to ang...@googlegroups.com
I think services are made for this very need.  The service should contain your model instead of the controller - took a while for that to sink in, but once it did, my controllers are easier to write.  A service is injected into your controller only to interact with the view and it maintains state for the life of the app.  It doesn't matter that there will be a large number of services that I can see. To put the data on rootScope sounds like a nightmare to manage especially if you have a lot of shared state, for one, you could accidentally overwrite data because of scope inheritance.  At least with services you get a name space and have to purposely assign values.

I recently wrote a filter for our users that has different contexts and maintains states.  I build the data model and it's basic functions in a service.  I inject that service into the a directive that manages the ui interaction, and I also inject it into the controller for the list of items to respond to.  The net result was that my controller was very easy to write and wasn't so tightly coupled to the view had a I written it on scope (or rootScope). Also, the directive made it easy to just drop in the filter where I needed it without duplicating code.  All the controller had to do was watch when a value changed on the service and respond to it by updating the list.  (Not to mention that the state of the filter was maintained after leaving and returning).  

I wouldn't use local storage unless you want the data to be remembered after the page is actually loaded anew and don't want to store state on the server.  

Aleck Landgraf

unread,
Mar 17, 2014, 2:02:09 AM3/17/14
to ang...@googlegroups.com
For keeping track of search information, I've had luck pulling out search or filter parameters of the $route, and putting them in with $location

           .when('/quoteOne', {
            controller: 'quoteOneCtrl',
            templateUrl: 'quoteOne.html',
            resolve: {
                'search_payload': ['search_services', '$route', function(search_services, $route){
                    var params = $route.current.params;
                    var q = params.q || "";
                    // params: (query, number_per_page, page_number, order_by, sort_reverse, params) 
                    return search_services.search_buildings(q, 10, 1, "", false, params);
                }],


and to add them:
$location.path('/quoteOne').search('q=' + $scope.search_input);
 
-Aleck

Rajesh Elumalai

unread,
Mar 17, 2014, 6:24:49 AM3/17/14
to ang...@googlegroups.com
Thank you, Rob! I like the idea of using a generic service - will explore on those lines!


--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/jjIJnaGi3_E/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.



--
Regards,
Rajesh

Rajesh

unread,
Mar 17, 2014, 6:31:53 AM3/17/14
to ang...@googlegroups.com
Thank you for the solution Aleck! I use a directive to load the filters and show the filter values on the page, so I would prefer to have this stored in a service or rootscope. Going by the other suggestions, I am leaning towards a service.

Rajesh

unread,
Mar 17, 2014, 6:44:12 AM3/17/14
to ang...@googlegroups.com
Luke, thank you for the detailed answer. Our current design includes the directive part of your solution, but state is maintained on the rootscope. I am convinced by the option of injecting the service in both the controllers and the directive. Thank you again for the detailed and helpful answer.

Alejandro Such

unread,
Mar 18, 2014, 2:34:12 AM3/18/14
to ang...@googlegroups.com
I have a similar app where I am using a service based on local storage. It works for me because it also has the option ti resume a quotation in the future, even if the user has closed the browser.

Regards,
Alx

Reply all
Reply to author
Forward
0 new messages