There's no doubt in the fact that one who is going to start writing a new app today would not be choosing angularJs framework, however thousands of AngularJs applications do exist as many companies who have started off with it use it till today, safe to say AngularJs isn’t going anywhere.
Most of the application examples I see in AngularJs are mostly in a controller-view structure (using ngRoute), we can achieve better functionality when we couple components and ui-router modules, Developers from later frameworks (Angular, Vue, React) would be familiar with this architecture, It gives powerful functionality compared to ngRoute. Let's get started.
To access the full source code, click here.
What is a UI-ROUTER?
UI Router is a routing framework for AngularJS, whicha allows you to organize the parts, or components of your interface into a state machine. Unlike the ngRoute module, which is organized around URL routes.
Let us take a small example of contact directory app:
UI-Router(state) Vs Ng-Route
In state approach, the views are tied to the state, whereas in ng-route, views are tied to the browser url. Here's an example:
In this case, we can selectively load only the messages component and details component when ever the contactId changes, avoiding to re render the contacts component ie you can load only the components tied to that particular state avoiding to load the parent components.
Functionality provided by UI-Router
UI-Router states
UI-Router nested views
A nested view is a child view to a particular state,
Example-
/home/info
/home/list
Here both info and list are the child views (nested views) of /home, and you can activate any one state and the corresponding view is rendered
UI-Router named views
Lets say you have two components both should be rendered for a particular state then we need to name the views so that we can configure to say which component should be rendered in which view.
Here's an example:
/contacts/{contactId} which is a child state to /contacts
Here we have two components — messagesComponent and detailsComponent which need to be rendered then we name each nested view with a name. The name of a view is given using name attribute, something like this,
<ui-view name=”messageView” ></ui-view>
<ui-view name=”detailsView”></ui-view>
Then, you have to configure to render which component in which view, like this,
<ui-view name=”messageView” ></ui-view>
<ui-view name=”detailsView”></ui-view>
Finally, configure to render which component in which view, like this,
views: {
‘messageView@contacts’: ‘messagesComponent’,
‘detailsView@contacts’: ‘detailsComponent’
},
Components - What, When, Why, and How
What is a component in AngularJs?
Component is a way to create re-usable isolated entities. It's the same as a directive. The main difference being that it is always isolated scope unlike a directive where u can choose whether it should be isolated or not.
The reason a component is always isolated is because, in a large application when $scope Inheritance or watchers are in play, inevitably there will be problems. Ot will be difficult to know which part of the application has actually updated a particular variable, here components works better(isolated scope).
When should a component be used
A component should be used when you are writing an application in the component architecture(I would say if the application is not a component based one no need of components you can use directives for other purposes).
A component is restricted to 'E', so if u want a directive which needs to be triggered by Attribute or Class use directives instead.
Why a component should be used
How a component is created
angular.module(‘angularApp’).component(‘messagesComponent’, { templateUrl: ‘/client/components/messages/messages.html’, controller: messagesController,
bindings: {
contact: ‘<’
}
});
Lets see some implementation of contacts directory app (mentioned above),
We have three components (refer the component hierarchy image above)
Adding routes and states
Lets add /contacts route and name the state as contacts
//app.js
var app = angular.module('angularApp', ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider.state({
name: 'contacts',
url: '/contacts',
component: 'contactsComponent'
});
$urlRouterProvider.otherwise('/contacts');
});
// main.html
<ui-view></ui-view>
Explanation
We have created a <ui-view/> in main.html which is the main view of whole application.
When contacts state is active then the contactsComponent is rendered in the <ui-view/> of main.html
Now lets add a child route to /contacts with named views
//app.js
$stateProvider.state({
name: 'contacts.person',
url: '/{contactId}',
views: {
'messageView@contacts': 'messagesComponent',
'detailsView@contacts': 'detailsComponent'
},
resolve: {
contact: function (contactsFactory, $transition$) {
return
contactsFactory.getContact($transition$.params().contactId-1);
}
}
});
//contacts.html
<ui-view name="messageView"></ui-view>
<ui-view name="detailsView"></ui-view>
Explanation
We have created contacts.person which is a syntax(dot operator) to append child state to a parent state so now person is a child state to contacts.
We have created two <ui-view/> tags and have given each view a name
Now in views property we have mentioned
‘messageView@contacts’: ‘messagesComponent’,
Which is to say to render messagesComponent in the view with name messageView. So, now when person state is activated then the components are rendered to the respective views mentioned in views property
How to navigate to a particular state
Through controller
$state.go(‘contacts.person’, { contactId: contact.id });
Through view
<a ui-sref="contacts.person({ contactId: {{contact.id}} })">Contacts</a>
Conclusion
I would suggest to build the application in this model itself, for better performance, fast and clean application.
Repo for the complete source code
https://github.com/Thejeshwar-Reddy/AngularJs-UI-Router
Check out this 55+ tech podcasts to know more on how digital devices have change our lives.