Proper way to handle three completely different layouts in AngularJS &UI-Router? - angularjs

What is the proper way to switch between three completely different layouts using AngularJS? Route variables? Populating the root scope? Nested controllers? Some magical method of maintaining the variables after causing the browser to navigate to a different URL without routing? I'm using UI-Router.
NOTE:
I am leaning towards using nested controllers however I'm stumped as how to target a specific UIView. For example, if a nest a view for a side-nav area, how can an sref (or similar), from the side-nave, change the main-body area?
My client handed me a static version of their site with 100 useful page samples, however the overall layout of many pages is drastically different. They all have data elements that would all tie together:
Semi-Public Area (approx 15 pages)
Similar to a public marketting web site but with a title bar, showing notifications for the user IF they are logged in.
Dashboard (approx 45 pages)
Complex pages for use in a web-based admin application.
User Application (approx 40 pages)
The actual public application. Changes made in the Dashboard must show in real time during this same session.

Related

Why is React Js called as Single Page Application

Hello guys i am new to React Js i often hear and see posts regarding react is single page app but never understood what is SPA and many say that it doesn't reload the pages but i didn't understood why so could you guys please explain me with simple examples.
A Single Page Application is a web application or website that interacts with the web browser by dynamically rewriting the current web page with new data from the web server, instead of the default method of the browser loading entire new pages.
This means that the URL of your website will not change completely (page will not reload), instead it will keep getting content and rewriting the DOM with it instead of loading a new page.
The goal is faster transitions that make the website feel more like a native app
Example: Netflix
This is the dashboard, and when we click on any movie, it changes to /watch and the content is rewritten.
In Technical Terms:
When building your react-app, you can see that there is only one
App.js from where your entire web-app is loaded in fragments and
components. This behaviour of rendering components and pages on a single page and changing the DOM( is a single page behaviour and hence the name), instead of loading a new page with new content, this makes it feel like a single application.
As mentioned in Glossary of React Terms:
A single-page application is an application that loads a single HTML page and all the necessary assets (such as JavaScript and CSS) required for the application to run. Any interactions with the page or subsequent pages do not require a round trip to the server which means the page is not reloaded.
And about "Why is React Js called as Single Page Application":
Though you may build a single-page application in React, it is not a requirement. React can also be used for enhancing small parts of existing websites with additional interactivity. Code written in React can coexist peacefully with markup rendered on the server by something like PHP, or with other client-side libraries. In fact, this is exactly how React is being used at Facebook.
A single page application has one single page e.g. www.google.ch. It is exactly one HTML file (with all its required dependencies) loaded into the browser. You'd navigate between paragraphs only using hash-router, but never ever visit another page like www.google.ch/maps (that would then be www.google.ch/#maps, which references / -> index.html) (tho google may not be the best example, it is more about URIs).
ReactJS is an open source JS library for building UI and used for SPA, and it manages the views of web apps. Reactjs can help you to modify your data without reloading of a page. It is a popular library in the market trend because of its scalability & fast performance.
Single Page applications are different from multiple page apps that we see everywhere because the SPA doesn't move into new pages; instead, it will load the pages inline within the same page.
In traditional websites, when we go from one page to another, the whole site is loaded. e.g - if you go from "www.example.com/hi" to "www.example.com/hello" the whole website is reloaded. No matter how much portion of the website is really changed. Let's say, the website has "Sidebar, logo, menu" on both of its pages, then the full reload doesn't make any sense. This takes too much time and decreases the performance.
Single Page Applications, as the name suggests, have only one single page that is loaded the first time you open the website. After this, no matter where you click, it is not gonna refresh the website fully.
browser reload button
The loading icon of the browser doesn't load when we move from one page to another on SPA site, as it does on the traditional websites.
Cons- SPA sites are great for UI UX but they are not the best when it comes to Search Engine Optimisation, it creates problems with rankings.

Why UI router if I can use directives?

Well, I have never used and never felt like that I should use the UI router. I was asked in one of the interviews about this and so felt like reading if I am missing something out as an AngularJs developer.
Now, the explanations on internet displays it's strength based on the modularity and reusability of the components. Nesting of views etc.
If I want to reuse components in my view, then can't I use directive instead of a new state? According to this article by scotch.io(top google result) for ui router we can use separate data /controllers in my view. Well, can't I do the same via directive's controller and template. I can still reuse as many times as I want it.
Please let me know if I am missing some cool feature and makes it quintessential to use it in an AngularJs application (yeah a larger one with lots of reusable components of course) .
The whole point of the router is that it uses the URL to change states. If you just used directives, you would have to write your own mechanism for syncing up URLs with specific directives.
AngularJS is a framework for Single Page Application.
Single Page Application (SPA)
Single Page Application is a web application that loads single HTML page and dynamically updates a fragment in the page as the user interacts with the app.
John Papa's blog explains SPA in simple terms.
The biggest advantage of SPA that I see is
once the application is loaded, the state is maintained without
requiring server roundtrip when user navigates.
Users can bookmark deep link into your application. SPA framework (AngularJS) will take care of loading the required state when user open bookmark.
Although it is technically possible to achieve the above in a non-SPA application, it was never as simple as SPA.
SPA is useful for highly complex applications with many pages. For simple applications with 2-3 pages jQuery is the way to go.
Read Single Page Application: advantages and disadvantages for more discussions
You probably know all these and I think you are trying to achieve SPA using directive.
Routing
Routing framework loads a view dynamically based on user action into the main page without refreshing the whole application; providing SPA effect.
There are two popular AngularJS routing frameworks available.
ngRoute
UI-Router
ngRoute is based on URL mapping and UI-Router is based on state name mapping. I prefer UI-Router.
Routing vs Directive
Now, the explanations on internet displays it's strength based on the
modularity and reusability of the components. Nesting of views etc.
Yes directive is used for modularity and reusability and can load views dynamically but cannot choose a view dynamically based on user action. You have to write complex conditions within directive to choose a view dynamically.
For example, if you have an application with 3 links and you need to show a view based on the link user clicked.
Using directive you need to keep track of what the user clicked and write a mucky condition to choose a view to display. Most of the time you will fail to achieve the effect because the link can be accessed in multiple ways.
On the other hand, once routing is configured, the corresponding template will be dynamically loaded when user clicks the link. It is way easier to change the view based on user action.
Another advantage. When user opens a bookmark deep linked into the application, routing framework will take care of loading the sate (It is impossible to achieve this using directive). It feels more natural way of designing an application.
Choice is yours.

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

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?
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
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.

Why is single-page apps faster when it generally has to make more requests per page?

How are single-page apps (SPAs) supposed to be faster when generally SPAs have to make multiple requests to get data for different parts on the page? As opposed to rendering server side, where the browser only has to make a single request to get the whole page?
I also remember reading somewhere that opening/closing a web request is the bottleneck sometimes in web requests.
So why does an approach that makes more requests per page is supposed to make web sites faster?
Because you only load what you need.
For example, on a "normal" web page, the menu, sidebar, etc. would have to be rerendered on each page, but with an SPA only the content gets changed.
In addition, think of this case: A website that displays 100,000 items on the front page (with pictures). In the traditional case, it will take a long time to load the page, but with an SPA you only load the "first screen" (i.e. what the user can see), and load the rest as he scrolls down.
In other words, SPAs aren't magic: it's just that they only need to update the bits of the page that change, which makes the response time lower for users (i.e. they can "use" the new contact faster).
If well done, they are faster because:
Part of the server workload is offset to the client.
Only the needed page fragments are loaded at any given time.
Redundant templating code is reduced. One template can style many items, as opposed to having to output a lot of HTML for a full page at once.
They also facilitate lazy loading and the download of new data during idle times, and parallelism: the concurrent downloads of elements.
Usually SPA are built with a lazy mode approach: get the info only when you need it and if you need it.
Also usually the data coming to and from the spa is in a format (json for example) which focuses on the data only. The presentation layer is a concern of the SPA and all the required assets should be already loaded.
So usually they are faster and more maintainable.
It is not always the case though.

Multiple index.html pages angular

I'm brand new to angular, and am still deciding whether or not I want to use it. I'm looking to have 2 separate 'base' pages in my app: an authenticated one and an unauthenticated one. They have different skeletons with different content areas. So, I can't just redirect to separate partials, but rather an overall html.
Is there a way to have 2 apps, 1 for index1.html and one for index2.html?
OR
Is there an easier way to do this? Or is this just not what angular is built for?
You can use ngInclude to conditionally change the contents of various parts of the page. That way your header and footer can change depending on whether or not the user is authenticated, while the main content area is still serving content based on your routes.

Resources