I am converting my application from ngRoute to uiRouter. I have read and watched a lot of tutorials but I am still lacking the experience to decide on best practices.
First of all a major change I have done is break the state declaration to each module/controller. This feels more natural and cleaner to me but introduces some complexity when wanting to apply a global rule to many states. For example half my routes require authentication and the other half do not.
With ngRoute I had a data attribute denoting the auth level required in each route. With uiRouter I understand there is this way of doing it and there is the state inheritance way. So a route could be public.myRoute where public is an abstract route declared at the application level. This creates the issue though of the module not being able to work standalone if someone does not define the public state.
In contrast if I add a metadata attribute in the data object, like "auth_level: user" this would not affect the module if no one is dealing with it. But this feels more "magic" and less maintainable.
The same issue arises with the navigation bar. Half my views have a navigation bar and the other half don't. Until now I used a isNavbarVisible boolean attribute but I understand this should be part of the state? Maybe a second ui-view in the layout.html template instead of using ng-include with ng-if as I did so far?
Finally, I am wondering about the best practice in requiring a promise in every route to be resolved. For example, no matter where the application entry point is, the user rights should be resolved first before loading the view. In ngRoute I was looping through all the routes in their definition and adding that promise.
Is there a good guide for best practices when migrating from ngRoute to uiRouter, because other than generic recommendation like "replace ng-include" with a name ui-view or that state inheritance should be preferred, I haven't found any concrete implementations demonstrating that.
I am in the same situation than the question author, Here's some very interesting information about how to drive this change.
https://github.com/angular-ui/AngularJS-StyleGuide
ui-router is a 3rd-party module and is very powerful. It supports everything the normal ngRoute can do as well as many extra functions.
Here are some common reason ui-router is chosen over ngRoute
ui-router allows for nested views and multiple named views. This is very useful with larger app where you may have pages that inherit from other sections.
ui-router allows for you to have strong-type linking between states based on state names. Change the url in one place will update every link to that state when you build your links with ui-sref. Very useful for larger projects where URLs might change.
There is also the concept of the decorator which could be used to allow your routes to be dynamically created based on the URL that is trying to be accessed. This could mean that you will not need to specify all of your routes before hand.
states allow you to map and access different information about different states and you can easily pass information between states via $stateParams.
You can easily determine if you are in a state or parent of a state to adjust UI element (highlighting the navigation of the current state) within your templates via global $state provided by ui-router
Overall, ngRoute merely allows you to assign controllers and templates to URL routes, whereas the fundamental abstraction in ui.router is states, which is a more powerful concept.
Related
I am building small app using angularjs and nodejs and i would like to know what is best use case for $stateprovider and $routeProvider.
Please help
Angular's own ng-Router takes URLs into consideration while routing, UI-Router takes states in addition to URLs.
States are bound to named, nested and parallel views, allowing you to powerfully manage your application's interface.
While in ng-router, you have to be very careful about URLs when providing links via tag, in UI-Router you have to only keep state in mind. You provide links like . Note that even if you use in UI-Router, just like you would do in ng-router, it will still work.
So, even if you decide to change your URL some day, your state will remain same and you need to change URL only at .config.
While ngRouter can be used to make simple apps, UI-Router makes development much easier for complex apps.
$stateprovider is used when you want the app to have different states like if you want jst a small section of a screen to be loaded at times instead of the entire screen, the go for State provider and the $state.go(url). Special cases when you have a Sliding Drawer sort of an implementation, where you have a right menu with buttons which load different sub screens.
$routeProider are commonly used. Mostly when you want the entire screen to be changed and redirected to a new one.
Note
While using the $state.go(url); for redirecting your screen, the real link of your screen won't change. It will just change the state and not the url of the page
Not to confuse the issue, but there is a new option in AngularJS 1.5: ComponentRouter
This router, along with the uiRouter ($stateProvider) give you more flexibility than the legacy ngRouter ($routeProvider). The ComponentRouter and uiRouter both have a future if you migrate to Angular2.
That said, it depends on your needs. You may not need the composable and nested views offered by ComponentRouter and uiRouter -- but instead only need simple routes.
I am from Asp.Net world, trying to understand what an Angular State mean.
What is an Angular State? Is it similar to an ascx component in Asp.Net? Is it a sub page? Is it similar to a workflow state?
I heard many people talking about it, and I have been trying to search for articles which explains what a state is or does, but cannot find a good one for the beginner.
Do any of you know any good article? could you please help me to grab/understand the concept of angular state? thanks a lot. :-)
The reference is not to Angular itself but to an Angular Module called Angular UI.Router. This module allows you to turn your Angular application into a State Machine, and handle what appears on the view based on these states, rather than only on the URL parameters. Many people consider this an essential Angular Module, and far more functional than the default $routeProvider.
The best reference for all the $stateProvider
features is the github repository wiki.
From the documentation for the AngularJS UI-Router,
A state corresponds to a "place" in the application in terms of the overall UI and navigation.
A state describes (via the controller / template / view properties) what the UI looks like and does at that place.
States often have things in common, and the primary way of factoring out these commonalities in this model is via the state hierarchy, i.e.
parent/child states aka nested states.
I'm working on an isolated scope custom directive that has a few different states.
Does it make sense to use ui-router/ui-view inside this directive in order to handle the states?
It's a "note widget" that lists notes. If there are no notes, it displays a message instead of the list that says they should add a note. If notes are being loaded, it shows that notes are being loaded. If a user adds a note by clicking the add I mentioned above or the + then the view is a textbox. So there is at least 4 different views.
My initial instinct is that it would be polluting the directive and giving it a hard dependency to ui-router and my application because it defines the states. Am I just over worried?
I would tell it this way: yes, use the ui-router, but not for a directive - use it for your appliation. In fact, the best you can do is to read few blog posts and go through sample application to understand the principles. You'll soon realize, that there is no need to use the ui-router partially..
from The basics of using ui-router with AngularJS (by Joel Hooks)
...ui-router fully embraces the state-machine nature of a routing system. It allows you to define states, and transition your application to those states. The real win is that it allows you to decouple nested states, and do some very complicated layouts in an elegant way.
You need to think about your routing a bit differently, but once you get your head around the state-based approach, I think you will like it...
and here AngularJS State Management with ui-router (by Ben Schwartz)
...The most interesting thing about AngularJS's new router, isn't the router itself, but the state manager that comes with it. Instead of targeting a controller/view to render for a given url, you target a state. States are managed in a heirarchy providing inheritance of parent states and complex composition of page components, all the while remaining declarative in nature...
Here I put together all the links, up to date, targeting the sample example, the most interesting code snippet sample.js..
Summary, try to implement the ui-router on the application level. Directive could then by a conductor only, helping your users to navigate, to walk through among states...
There are two ways (AFAIK) to associate a controller with a view template/partial: the route specified in $routeProvider and the ngController directive. Especially (but not exclusively) for simple routing, is there any benefit/efficiency of one over the other?
My project currently uses the $routeProvider approach, but I've been given the task of nesting views. This seems simple enough with ngInclude, as long as the partial specifies its ngController.
This question really comes down to design and as such it is a bit opinion based. That in mind, the best guidance I know is:
$routeProvider - Allows you to specify a single controller for a template. Since this is part of the routing it makes it easy to find the controller that goes with the page. I use this to store and load overall page logic rather than element specific logic.
This is also important because it means you can load the exact same template for two different routes but the behavior and data could be different because the controller can be changed. This is not something that is easy to do with the ngController option.
ngController - This scopes the controller to a specific element on the page/template. That can make the code easier to read when you need multiple controllers on a single page and it allows the controller to be more specifically scoped.
So it really comes down to scope and intent. Hopefully these rules will help when deciding which to use.
If you think of a view including all scripts as a self-contained package, developed by a single person or team, then ngController is the way to go, imho.
$routeProvider on the other hand provides you with advanced features like injection of values via the resolve property of the route. That way you can have your AJAX loaded data directly injected into your controller, e.g., instead of the controller having it to get itself. Or have the route change to wait for that data etc.
Btw: If you need routing and nested views you can take a look at angular ui-router
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