When programming using angular.js the routers control the view, they are the link between the page url and what you see, what templates and controllers are shown on the page.

In the Angular (1.x) ecosystem there are 3 main routers.
* The standard router. angular-route
* Angular-ui’s router ui-router
* Angular-route-segment angular-route-segment

Segments
One of the notable features is the ability to change segments of the page. Being able to have nested views, this is useful if you have a dynamic header with dynamic main content section. This isn’t in the standard router, but is in ui-router and angular-route-segment. You could use nested views in the router to implement the design in figure 1. Of course you can do this yourself with a dynamic ng-include, but ui-router and angular-route-segment do it better.
Figure 1

Loading Data
Another notable feature is the ability to load data before loading a controller. ui-router has this idea of state where you can resolve data and inject into the controller.

One effect of this is it can wait loading before showing the page, rather than showing the page then populating the data with data binding when its ready. So when you have a link to a new page, the user clicks it expecting to be taken to a new page and seeing the data for the new page. With the a blocking depenency resolver the user clicks the link, nothing happens while the data loads, then they are shown the new page with the data. Without blocking dependency you have to do the data loading in the controller, the user is immediately shown the new page and shown the data when its populated. I think the later is better. Obviously with both you can implement some sort of loading bar to entertain the user while they wait.

Another thing about the resolvers is that you can add ridiculous logic in there that I can’t figure out how to test. See the code bellow, the resolver for dataZ. The alternative/better way is to push that code into either a service or the controller. But making it hard to test stuff is dumb.

$stateProvider.state('page1', {
  url: '/page1',
  templateUrl: 'page1.html',
  controller: 'Page1Ctrl',
  resolve: {
    dataX: function($http){
      return $http.get('/dataX');
    },
    dataY: function(DataYService){
      return DataYService.getit();
    },
    dataZ: function(DataYService){
      function changeItSomehow(item){ .. }
      DataYService.getit(_.map(changeItSomehow));
    }
  }
});

Query Parameters
Something else that ui-router adds is a state parameters, which are essentially url query parameters. In ui-router you to to urls with $state.go(’toState’, {queryParam: ‘value’}) with $stateParams.queryParam. In angular-route ur angular-route-segment you just use  $location.path('/newValue').search({key: value}) . This is a pretty small difference.

Conclusion
I think ui-router is a little too fancy, the resolver is hard to test, and is only useful if your doing weird things. Nested views is a pretty essential though, you can do it yourself with angular-route but its better to use either angular-route-segment or ui-router. angular-route-segment doesn’t try to change or replace any of the standard angular or angular-route features, it just builds on them.