Hiearchical Routing in Single Page Application - javascript

I am building a single page app. I have been playing with AngularJS. I'm a little nervous about 2.0 so I am open to alternatives to Angular. My challenge is, my site has a hierarchical structure.
/Home
/About
/Blog
index.html
post1.html
post2.html
...
/Products
index.html
product1.html
product2.html
...
index.html
/Contact
/Online
form.html
index.html
Most SPA apps I see are only one level deep. In addition, I can't animate the navigation items associated with each level. In other words, when I click a link at the top level, I would expect the sub-navigation items to animate in. The other problem is dynamically loading content. I don't want to load my app when it initially loads, instead, I want to defer loading of content until its needed.
Can anyone recommend a SPA framework to help me address this challenge? I don't think I can tackle this problem with Angular 1.3. The router in Angular 2.0 look like a potential option. For now though, it does not look viable.
Thanks!

My challenge is, my site has a hierarchical structure
There is nothing about SPA or AngularJS that makes a hierarchical structure harder than a 1-level flat structure. The built-in angular router can handle this just fine.
In addition, I can't animate the navigation items associated with each level.
Well, post a detailed question about that, but maybe take a step back and think about "animated navigation". Sounds like low-usability, distracting, unnecessary behavior to me. You look to be building a basic marketing and sales site for some company. Not sure animated navigation should be a major concern.
I don't want to load my app when it initially loads, instead, I want to defer loading of content until its needed.
This is also almost certainly premature optimization and misuse of engineering cost/effort. Defer loading of content (HTML and text) perhaps but probably not code (javascript). Splitting an app up into deferred-loading modules is for apps with 100 developers and huge codebases with multiple complex areas (think airbnb, facebook). Chances of you realistically needing to do this and having it be a worthwhile effort (cost/benefit) for your stakeholders are extremely slim.
I don't think I can tackle this problem with Angular 1.3
I'd recommend trying with the built-in angular 1.3 router first and if you end up wanting multiple distinct states at the same URL path, check out the angular-ui-router.

Related

angular 6 Multi-Page App How to

I'm developing a complex information system, and our front-end stack is defined to use Angular Framework. I'm aware that Angular was planned and mostly suitable for Single-Page Applications. But at this stage, I'm facing an issue with MPA support from angular 6. Basically, our client's requirement is that to view certain element in a system, it has to be opened in a different tab because normally people will open multiple and use it to gather or compare elements between each other.
My current app is distributed among multiple lazy loaded modules, so my question is what is the best way to implement MPA support for angular, in order to solve this issue? I know that if I open a link in a separate tab, the whole application has to be downloaded by the client and only then he can view the particular page. Can anybody advice on maybe certain solutions for this case, or whether its possible to not download the whole app on a new tab? Thanks.
PS. I've browsed through the whole internet, but haven't found any solution for this.
I am working on a multipage app using angular these days. There we use normal location.href navigation for routing rather than using the angular router module. This way angular app can be used as a multipage app. When we do this, every time when we are reloading the browser, angular bootstrap everything and loads from app component onwards. So when you use lazy loading, you can limit the the no.of modules loading every time the browser refreshed. same happens when you open something in a new tab.
As suggested by #Suresh Kumar Ariya, server side rendering is to just render the static content of a page while the javascript files needed for the dynamic functionality of that page loads in the background. So I don't think this is what you are looking for unless you wanna just serve static content fast for user experience improvement.
What you can do is try to do more lazy loading to minimize the initial loading and optimize your code
You can also opt for Angular with Service Side Rendering Concept. So Data can be shared b/w client and server end. https://angular.io/guide/universal
Thanks everybody for advices, solved the issue with service workers, now all tabs are loading instantly =) thanks to #Patryk Brejdak

Real world webapp structure with Spine.js

I've been diving into JavaScript MVC for quite a while using Spine.js and CoffeeScript. I develop Ruby on Rails since a while so I understand what the models, the views and the controller should handle respectively (based on my moderate experience with it). But in Rails we already know that (generally speaking) each controller is basically something that controls a bunch of views (or pages) and deals with one or more Models at a time. (Maybe, so correct me if I'm wrong as I'm not a pro yet I have to confess).
However I found a whole different concept with Spine in terms of architecture. I read its documentation and dove into its sample apps. Unfortunately all the Spine sample apps are showing how to deal with a single page app, something that in a real world "larger" application would not be the case anymore. (Correct me if Spine should only be used for "single page apps").
Assume there is a website (or app) that consists of many pages/sections/modules as follows:
1 - A home page, displaying for example, a thumbnails based list
2 - A contact page
3 - A profile management page for the current user (normal CRUD)
Each page has the same main structure (or layout) as in a header with links to the above pages, a search input field and a log out link (I already know the log in page should be separate, so I won't ask about authentication in here).
The tricky part here is I can't really figure out how to tie the whole parts together and I've been asking myself some questions, searched on Google and StackOverflow but without clear answers.
1 - "Must" a spine app application be in one page only? I mean, having header and footer fixed but with a dynamic content DIV which loads and unloads views based on which tab the user clicks on the header? Or should I treat each page as a standalone spine app?
2 - Do I have multiple controllers in one page? For example, the app main controller and navigation controller (header)?
3 - Is it true that each controller should be dealing with one Model, or the one associated with it? (In the samples there was always a 1 to 1 relationship between them, like Task Model and Tasks Controller).
4 - Where should I store interface related state variables in my app. Should I create a model that "remembers" the current user, or for example which tab is highlighted for further reference? Or should I store them into the controller(s)?
5 - If it's going to be a single page app (but with many sections or modules), should I have a controller for each loaded section inside of this page?
I know these might be trivial questions for more experienced programmers but I really don't know where to start. So it would be awesome if someone could guides me to the right track.
Thanks in advance!
DD
I think that this is a very good question. My answer will be quite broad, so bear with me.
The essence of my answer is that you need to get familiar with other frameworks in order to understand what the one you chose is trying to solve. Your problems are understandable. Other people have struggled with lack of one "proper" way of doing some common things. Solutions were created in terms of examples, wrappers/extensions and alternative frameworks. Perhaps, you should seeks information related to Backbone, which inspired Spine and is still similar to it.
As you said, you're familiar with Rails' MVC. And then comes Spine's MVC approach and it is totally different. This should give you a hint that MVC (or MV* in general) is broad idea that has very different implementations. OK, you might be thinking that Rails is a request-based server-side framework after all and that Spine is a client-side event-based framework - so the difference is understandable. Well, there is no uniformity amongst client-side JavaScript frameworks either. For example, the mentioned Backbone has so-called Views, which actually play the role of controllers. So I guess that one thing that Spine's creator did was renaming Views to Controllers for clarity. MV* for JavaScript is explained in detail by Addy Osmani. There is also a good overview of JavaScript frameworks.
So one "problem" with Spine and Backbone is that they do not dictate any architecture. In other words, they are not opinionated enough. You can use them as your want and this fact makes frustration. Below I try to answers your questions:
With Spine, application is not required to be a single-page application (SPA).
You may create an app that has multiple pages, each loading it's own Controller. In this case, your views can be rendered on server and your models can be bootstraped from generated JavaScript. This is good when you don't want a SPA, but still would like to organize JavaScript or have some reusable components.
However, judging from the feature set of Spine (e.g. routes), it was created with SPA in mind.
For SPAs and complex UIs in general it is good to have parts of UI (widgets) separated. In Spine, Controllers are the means of such separation. So yes, use multiple controllers and use controller nesting. Perhaps, there should be a topmost application controller.
That's not true (no technical limitation), although single responsibility principle makes things easier.
Store those variables in the controller of corresponding level. Store them is models if you need to observe those values, otherwise store them as controller properties.
You can have an App controller, that holds a header, footer, sidebar controller and an active page. In Routes, you create a corresponding controller and pass it to App controller, which replaces the main area content with the element of that controller. This is one possible approach.
Once again:
People have struggled with lack of concreteness in terms of application architecture in Backbone/Spine. They have created some solutions like application controllers, layout managers and so on. For Backbone, you can take a look at Marionette, Chaplin or Thorax. By learning from them you will be able to come up with an architecture for your Spine application. Good luck!

Structure large jQuery Mobile web apps: use iFrames as pages? Backbone, Spine, Underscore, and other frameworks?

We built a web app using jQuery Mobile. It's now nine pages and becoming very unwieldy. jQuery Mobile bundles all "pages" into the same page to simulate the responsiveness of native apps.
We thought about implementing each page as a separate iFrame. The first page contains every iFrame/page and preloads each one. Page transitions happens like JQM by displaying the appropriate page in the viewport. Data is passed between the master page and child pages through iFrame messaging. We think this might be advantageous since:
(1) it won't require additional frameworks;
(2) the web app won't grow beyond 15 pages/iFrames; and
(3) the web app will be accessed through a native app container (i.e., PhoneGap) not a mobile browser.
We're also exploring frameworks. From our research on SO and elsewhere, it seems like Backbone and Spine are two great options for structuring large JavaScript projects.
It's less clear how well they manage JQM projects in particular.
We're looking for three things:
1) What options and frameworks exist for structuring large JQM projects (MVC ideally or worst case, any improvement over a monolithic file)?
2) If you have used Backbone, Spine, or any other JS framework with JQM, please share what you liked/disliked.
3) Do you see any glaring problems with our iFrame architecture, aside from the fact it means building proprietary functionality?
Using iFrames seems to be not optimal especially when lots of different light-weight and easy frameworks exist.
JqueryMobile has it's own router. I didn't like it - using hash tags it requires the page with needed hash was in DOM. Of course, it's possible to load pages dynamically but you'll anyway need to create new pages, add them to page container etc. Such way of working with pages is not suitable for me and also overloads DOM.
Also working with JQM it's possible to use Jquery templates - they allow to store pages or different HTML code, that can be parsed later using passed data. These templates and parsing mechanisms seemed to me very simple and easy to use. But they are not suitable if it's needed to parse complex number of data. Also no support for partials (like in ASP.NET MVC). That means, that you cannot store header and footer in only one file and load them as partials for each page. You'll have to duplicate it for each page.
The rest functional of this framework is great. Lots of controls, theming etc. It seems to be a leader for UI creation - without any doubt. The only thing I didn't like - JQM page transitions.
Now about Backbone. It's a powerful and easy framework to create your app using MVC pattern. Actually, there is no JS framework that allows to create real MVC. But basics are true. Models, Views and Controller (Router). Simple creation of new routes, good documentation and lots of samples on GitHub. Powerful mechanisms to work with views and models - their site will show all the features.
I offer to use Backbone + JQM. But in this case you'll have to disable one of routers to avoid conflicts between these frameworks. Only one should stay.
About paging. There is no need to store all the available pages in DOM. You can create only one JQM page with content element and update it dynamically. Store html in templates, get data from services, parse templates and update content element.
Backbone has a dependency - underscore. At first sight, I didn't want to use Backbone because of this. But underscore is a powerful framework with lots of useful features. And one of them is - templating. Powerful parsing mechanisms for parsing - support loops, js functions, creation of variables in templates etc. Also do not support partials - but you don't need it, because no need to create new page all the time.
When my app had just few pages - I loaded all my js files (frameworks, helpers, service callers, views, models etc.) and stored underscore templates right on my html page. But supporting of such code is a horror. HTML page became huge.
RequireJS framework can solve this problem. It can load not only JS files, but also text templates (using text plugin). All the code in this case will be modular. It's well documented with lots of samples so there is no problem to see how it works.
By the way, the last versions of Backbone officially do not support AMD. But it's still possible to load it using RequireJS.
Also think about scrolling of your content. I won't write a lot about it. Just look at iScroll framework.
So, PhoneGap + Backbone + JQM + RequireJS = Success :)
Go with Sencha Touch, and replace all with it.
15 pages doesn't seem that large to me. I really don't think introducing another framework will make things easier for a site of that scale.
I have felt the same frustrations as you, but instead of putting everything in one giant file, have used ajax page loading to dynamically load pages.
To avoid collisions, I'm just careful to prefix identifiers with the page name. It hasn't been that much of a problem.
It's a little annoying that you have to copy paste the into every file (which makes testing a lot easier, and allows multiple entry points to the site), but I've been able to put up with it.
Despite the drawbacks, splitting pages into HTML files helps with the 'wieldiness', especially if you are inlining the javascript on the page.

Backbone.js Large mutli page app, manage page transitions cleanly destruction, creation etc

I'm currently building a huge backbone app (facebook clone).
Over the last couple of days, feeling pretty happy with how everything works in BB thanks to Rob Conery's excelent tutorial (essential viewing if your starting out with MVC 3 and BB http://tekpub.com/productions/mvc3)
Now I've come to the stage where I need to switch pages in my app, and I am starting to wire this up, but it feels like I'm doing a lot of this myself. This is fine, and I know I will be able to do what I want it to.
I've delt with the memory leaking issues, by making sure I unbind and remove my models/collections/views when switching page, Switching views in backbone for navigating between pages - whats the right way?
But aside from this stuff, there is a whole load of tasks that I want to do when I switch between pages. Essentially removing and adding parts of the page. This is slightly more complicated becuase rather than just removing everything, I'd like to only remove/destory the bits of the page that need to change, based on the transition I'd like to make.
As said, I'm getting it working myself at the moment, but I wondered if there was a pattern to handle this tear up / tear down process, and keep things clean (and not end up with a massively bloated router (controller bloat!!!)
Marionette is definitely the way to go. Specifically, Marionette.Layout is fantastic for swapping out specific regions without re-rendering the entire page. Check out some of Derick's Example Apps to get acquainted with the framework.
I'd recommend staying away from the Router until after you've gotten your app working using plain old events. Then add the Router support after. Basically the Router should be wired up to reflect the state of your app, but you should not depend on it to be your controller.
As an aside, I'm using RequrieJS on a large multi-module Backbone project and it's been a godsend. It's controversial in the BB community, but it's worth looking into if you'll have lots of inter-dependent components and you want to let another framework handle all the dependencies.
I had your same problem and wanted to share how I solved it, so I re-designed the ToDo App example from the Backbone.js docs using my page transition convention:
http://ahamlett.com/Backbone.localStorage/
I haven't tested it for memory leaks, but if there are some just call .unbind() before .remove() in the SetView method of the app's router.

Best way to structure a multiple page application in Javascript

As an Actionscript programmer shifting to JS/jQuery I often have to author multipage apps targeted mainly to iOS and I'd like to know what is the best way to structure such apps.
Most of the time my apps are presentations, where each page has a different behavior (i.e., some popups on page1, a group of sliders on page2, some drag and drop action on page3... you get the picture), and more often than not I have to keep track of several variables across different pages.
Right now I handle it like this: I have a group of common functions in a script named my_app.js, while each page has its dedicated pageX.js script to account for its specific duties. I store persistent values through the storage.js library and somehow manage to stick it all together and make it work.
However I recognize that there may be a vast area for improvement to this approach, so I'd like to know how more seasoned developers deal with this situation.
Thanks a lot,
Goblin
What you've done seems OK for a smallish app, but as another answerer said, I'd look at an MVC architecture. I can heartily recommend backbone.js, it's pretty lightweight, and simple to use.
You could easily make a controller for each type of view that you need (e.g. sliderController, dragDropController, etc) and then if you needed to, subclass ('extend') these controllers to be platform specific (e.g. iPhoneSliderController, iPadSliderController, desktopSliderController, etc).
If I had more info about this app - like the data behind it, what the user is achieving by dragging/sliding - then I might be able to give a more specific layout for the models, views, and controllers you might want. But hopefully this is a good starting point, and if you take a look at the backbone.js documentation, it should give you a good idea if it's appropriate for your app.
The structure you have sounds sensible enough (common JS file complemented by page-specific JS files). It also sounds like you're onto the right lines with storage.
What I would do in your situation is focus on how your code is structured in terms of architecture. Chapter 6 of Stoyan Stefanov's Javascript Patterns (O'Reilly) would probably be quite enlightening.
I would also probably explore JS MVC implementations given your situation would lend itself well to this methodology (lots of views).
I realise this is only scattered thoughts, but hopefully it might give you some ideas.
Here is how I organize stuff
in /
modFOO.php
modBAR.php
in /js/
main.js
resourceloader.php //this is a resource loader, so I can load multiple JS in a single request
in /js/pages
modFOO.js
modBAR.js //javascript that for page modBAR
in /css/
main.css
resourceloadercss.php //this a resource loader, so I can load multiple CSS in a single request
in /css/pages/
modFOO.css
modBAR.css
With this setup I know exactly where to find stuff, and where to put stuff. And based on the filename, modepic.css, I know exactly where to put the file, and what is (the CSS file for modepic).

Categories

Resources