Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maintaining application state across single page view flips and multi-page flips

Tags:

angularjs

Well, as technology progresses, issues we solved long ago crop up again.

Back in the dark ages, when PHP and ASP were considered awesome, we always had a problem with view states. If you had a page with say a dozen select combo boxes on it, your user chooses some combination and hits next, then realizes they screwed up and hit the back button on the browser, the combo boxes would be back in the default state, usually with option[0] selected. In order to prevent this, we had to write boatloads of boilerplate code that would save the state of those combo boxes to a cookie, or session variable, or something so that when the user hits the back button, we can reload the combo boxes back to the state they were in when they left.

This problem was compounded even further if you had a datagrid on the screen. Because then you would have to come up with some slick way of saving that grid somewhere to prevent from having to hit the database again.

Then came the light. Browser developers realized that most web developers were on the verge of going back to writing terminal programs in Cobol due to this issue and added UI caching to the browsers. This allowed us webdevs to not have to worry about this anymore except in odd situations.

So, life was good. Then someone came up with the bright idea of trying to replicate GWT without all the hassle and the web explodes with all these javascript frameworks. The one im dealing with specifically at the moment is AngularJS 1.2.10 with Angular-UI. I have until Friday (most likely wednesday tho) to make an initial assessment on if this technology is a viable alternative to our current standard (thats pretty much universally hated) JSF.

So, i follow some guides, pound my head against the desk a few times, and I have an angular app with 3 actual HTML pages, each HTML page with 2 views.

Before you go there, understand we can't use it unless we can do multi-page JS apps. Some of the applications that this will be worked into have been in development for a decade or more and its simply not financially practical to scrap an the entire UI and start over again. We would instead be doing things like taking these 50 struts pages and converting them to angular/rest and linking them seamlessly back into the remaining 800 struts pages of the application.

So in my exercise of playing with this, I encounter my old nemesis. Back button view state issues.

I have been playing with the UI-route system. The fact that I can deep link using the route system solves part of my problems. But, if say I have a search page like this:

view-search
    combo: search type [member,nonmember]
    combo: result type [detail,summary]
    combo: search state {all the states]
    textbox: contract number
    etc etc etc

And various combinations of combo box selections and text entries comes up with a list of 1000 people. Now the user selects one of those people on the data grid and it takes you to view-detail. Well the fact that you can use routing to do something like index.html#detail/bob is cool, but if the user realizes thats the wrong bob and hits the back button, they get a blank search screen again and they have to enter everything over and worse yet, send another search to the database to rebuild the datagrid. Some of these screens have 50 or more options to choose from when searching for data so trying to put all of them into the URL routing sounds completely impractical to me.

Now in my research I found this post:

Preserve state with Angular UI-Router

And that has promise mainly because I have a view state object that I can store into a Redis database or a session EJB for cases when the user actually jumps out of angular and into the legacy Struts application, then back buttons back into the angular application, but the fact still remains that on some of these pages, that is a huge amount of boilerplate code that we would have to write in order to make it work.

I don't really mind the idea of having to manually save off the view state object and read it back in from a Redis server or something anytime a user enters or leaves an HTML page in the system. What i'm really looking for is a way to automatically generate the object that is to be saved without having to write volumes of boiler code.

Is this possible? I keep reading the ui-route documentation but it doesn't look like this is addressed, at least not that i've translated yet.

If this is possible, what controls should I be looking at?

thanks

-------------- Edit

I just thought of something. There is one central scope to each of the single page applications. (Im basically going to be building a multiple single page apps and hooking them together) So if i use a naming convention, something like this

$scope.viewstate.view-search.searchType
$scope.viewstate.view-search.resultType
$scope.viewstate.view-search.searchState

Then the viewstate object should simply be a js array and when I create a function to move to struts.do, i can simply save that array off to the Redis server as a nested map object. Then when my user back buttons back into the angular app, i can capture that using the route system and retrieve that viewstate object from Redis and insert it back into my scope, thereby rebuilding the scope for the entire single page app in one shot.

Would that work?

like image 925
scphantm Avatar asked Jan 30 '14 01:01

scphantm


People also ask

What is difference between single page and multi-page application?

Ans 1) A Single Page Application is where the server sends what you need with each click, and the browser renders that information without the need to reload the page again. Whereas in the case of a multi-page application every change requests rendering a new page from the server in the browser.

What is a multiple page application?

What is a multi-page application? As the name suggests, a multi-page application (MPA) is an app that has more than one page. It works in a traditional way, requiring the app to reload entirely every time a user interacts with it. MPAs generally have large data and complex architecture.

Is single-page application better?

Single-page applications offer a much better user experience (UX), meaningthat users can navigate easily between the different pages of an app without waiting for the pages to load.

Can angular be used for multi-page application?

Angular is optimized for single-page applications (SPAs), but with a few simple steps it can also be used to display several applications on one page, a "multi-page application", so to speak. Lazy loading and shared code parts are even included!


2 Answers

I believe that you have a very complicated issue of trying to keep the view states between your varying pages with the amount of data in your pages. I think that the only real effective way to do this is to write an angular service that you can then pass to your various pages. as You already know the service is a singleton that you can use in various controllers and could be utilized to maintain the view state as you described. here take a look that this link and see if it will help: http://txt.fliglio.com/2013/05/angularjs-state-management-with-ui-router/

After some thought what you suggest in your edit might work, but I would still use a service to retrieve that array of data, as it would make it easier to reinsert in to angular scope

like image 186
Jared Reeves Avatar answered Sep 29 '22 10:09

Jared Reeves


I am exploring something similar for an Angular app that I am writing. Keeping a user login during a page refresh is easy. Displaying the state on the page after a refresh is an entirely different problem.

How long must the state be persisted? I'm evaluating two possibilities.

First, saving the state (current form values or whatever) to the database. As the page changes, incrementally save the state to the database. On a browser refresh check the database for saved values.

Second is to use local browser storage. This is 5 megs of storage. 5 megs is a lot of text. Again this data would incrementally be saved into storage. When the browser refreshed, simply load data from localStorage.

like image 39
Chuck Conway Avatar answered Sep 29 '22 08:09

Chuck Conway