AngularJS: Trying to understand the technology behind loading new content without reloading a page - angularjs

Using AngularJS 1.5.8 and Django/Django REST Framework as the back-end.
At this points have two URLs (app/ for login and app/dashboard as the main content); would be great to just have app/.
login and dashboard I have as components; navbar and sidebar I have as directives.
Using ngRoute currently and somethings I am reading lead me to believe I should be using ui-router to accomplish this.
Just some basic things that came to mind.
My sidebar has several tools I am developing. I want the user to be able to click on them, and then have the content related to that tool load in the main content area without the page refreshing or the URL changing.
Some of what I have read suggests ui-router might be better for this purpose? I am not, sure as I am just learning AngularJS and still struggling with its concepts. Thus, I don't have any code to post that needs to be fixed. Primarily just trying to understand the concepts and technology I need to look into to accomplish this. Makes it hard to lookup results on Google and SO when you aren't even sure what the terminology and tech is that you should be looking for.
Not sure if ngRoute or ui-router should be used; whether the modules should be built as components or directives; if the content for each tool stays in its own HTML template; etc...

This is a somewhat broad question but what you are looking for is client-side routing. Both ngRoute and ui-router offer this functionality and in very similar ways except ui-router offers significant extensibility with nested routes and multiple named view containers.
My advice is to start with ngRoute and learn it's ins and outs and then switch to ui-router if you find you need this extra functionality.
Client-side routing can either be used with the hash-bang (#/) or using html5 mode you can use a base URL that would function visually like server-side routing.
Now you've got the terms to search at least so happy Googling!

Related

Add an additional page to an Angular SPA

The Scenario
I'm developing the front-end (CSS only) of an Angular SPA.
I'm not especially familiar with Angular routing.
I'd like to add a standalone page containing Bootstrap components just for development purposes (yes, I know this means it won't be a single page application anymore). This way I have one unified view with all the components so I don't have to switch back and forth while working on the CSS. It also acts as documentation for the Bootstrap for the other devs to refer to.
What I've tried
I originally added a bootstrap.html page to the app folder, alongside the app's index.html This worked at first, but has now stopped working. What would be the best/standard way to achieve something like this?
Update: I've managed to fix some of the JS errors, so the page is up and running again. My question remains though: "is there a way of adding a standalone page that is considered standard/best practise, or is it literally just add a separate HTML page at the app root?"
If you use a target='_self' in your linking anchor tag, this should force a full page reload, and that will avoid the angular routing - which is where I expect your request is getting hijacked (by design).
e.g.
link
Answering your updated question
Not to my knowledge, since (as you correctly pointed out) this mixes the SPA design pattern.

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.

Use backbone routing without changing url

I have developed a webapp using backbone.js and more importantly a backbone router. Now I have been asked if this app that changes the URL depending on what section you visit, can be used within a single div as mini module on a website. Almost like a widget within a dashboard.
Any ideas how I could quickly implement this..... I feel like i'm missing a simple solution here.
Thanks,
Gary

What is the difference between $state.go(app.location) and $location.path("app/location")?

I have recently started using ionic framework, it has angular js in it. To navigate between screens, I was using $location.path and it's working great. However, in an example I've downloaded, I saw $state.go being used to redirect to some page. I would like to know the difference between the two.
The $location service is on the angular.js framework out of the box and allow you to manage location object (similar to that in pure javascript).
The $state service is a part of ui-router module and allows you to manage routes in an advanced mode, throughout a state machine management of views.
If you use ui-router, you should prefer to use $state service to manage states/routes because state abstracts the concept of route and you could change the physical routes without changing states.
Besides that, more problems you could have if you run in hashbang mode, in particular in your html links. In this case it's preferable to use ui-sref rather than ng-href (or just href).
In my opinion, you should always think in term of states rather than paths. Obviously you can mix the services if you know what you're doing
Thanks #wilver for answering it.
As I dug deeper into angular and learned different ways of structuring my projects, I got to understand these states and paths better. And yes, I've found states much better than paths.
$state.go, which comes with $stateProvider - a provider by ui-router, will work based on state names. Major difference between previously inbuilt(now you need to include ngRoute) router and states is that "States can have nested states but with router it's not possible. And I suddenly realized that whole of Ionic framework is possible because of this concept - I was able to understand this while working on an angular web app based on ngRoute and ionic app based on ui-router.
Ionic works with app as basic state and all other screens defined as its sub states. That's why you see app.screen1, app.screen2 inside $stateProvider in app.js.
So when you have routes, you use $location.path("<routeUrl>") and
when you have states, you use $state.go("<stateName>")
I use ionic and one of the differences that I have observed but not yet figured out why is that $location.path is much slower than $state.go

Keeping state when rendering page from the server side

I'm currently building a single page app using backbone.js
In order to keep all application pages accessible and crawl-able I made sure that the server side can also render the pages when accessing them directly.
The problem is as follows:
When pushState is not available it initiates the router using the current URL (e.g. if I accessed a url with http://example.com/example the router will build the hash fragment on top of that url)
So:
Is there any way of handling this (besides redirecting the use)
If you are redirecting as soon as the JS (using pushState feature detection) you still have a problem of urls not having hash signs.
Generally asking, is there a better approach of designing this kind of application?
Thanks!
I think the evolving consensus is pushstate or nothing (ie to degrade web 1.0 and drop hash-bang routing all together) if SEO-friendly browsing matters to you.
Its one of the reasons I don't use Backbone.js and just use PJAX is that pushstate and DOM rendering times are so good you can be single page with very little JS and hash-bang routing has always been rather hackish.
Thus an option is to not use Backbone's router all together and just let something like PJAX (or DJAX or something similar) do the routing work and let Backbone just do the inner page event/rendering stuff (ie validating forms, modal windows, etc..).

Resources