Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Angular routing alongside roundtrip routing

I'm working on a Django app which makes heavy use of Angular in some pages, e.g. at domain.com/myAngularApp

Within the angular page I'm using Angular routing for navigating between different views/states within that page. However across the whole website there are navigation links which need to result in round trip requests to Django. However all the pages include the same compiled javascript file which includes the Angular route declarations.

So my question is: how to I get Angular to mange its own routes and get out of the way when the location is changed (primarily by clicking a link on the page) to a path that it hasn't explicitly been told to own, i.e. to different subdirectories off the domain.

My routing declaration looks something like:

myApp.config( function($locationProvider, $routeProvider) {
  $locationProvider.html5Mode(true);
  $routeProvider.when('/myAngularApp/', {
    templateURL: 'template1.html'
  });
  $routeProvider.when('/myAngularApp/stuff', {
    templateURL: 'template12.html'
  });
  $routeProvider.otherwise({redirectTo:  <not sure what to do here...>  });
})

I've tried something like:

$routeProvider.otherwise({redirectTo: function(a1,r,a3){ window.location.href = r }})

But this makes the page refresh endlessly on any non-matched route.

Leaving out the otherwise statement seems to make it impossible to leave a page with a non-matched route when accessed directly... don't really understand why?

It must be possible to do what I want no?

like image 964
Nat Avatar asked Oct 03 '22 17:10

Nat


1 Answers

I think I may have found a solution. I'm doing a similar thing, a multi-page angular site that uses angular for some of it's pages. Here's what I'm doing

var app = angular.module('appname', ['ui.bootstrap', 'ui.autocomplete'])
.config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) {
    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix('!');
}])
.run(function($rootScope, $location) {
    var redirected = false;
    $rootScope.$on('$locationChangeStart', function(event, nextLocation, currentLocation) {
        if(!redirected &&  $location.path() !== '/current-url') {
            redirected = true;
            event.preventDefault();
            window.location = $location.path();
        }
    });
});

So what I have to work out next is how to pass in the current-url path. One way I'm thinking is to us ng-init to set that data in the view (I'm using express.js so I'd use Jade). Or possibly in the run function grab the initial path and test against that.

The event.preventDefault() is there to stop an extra item being added to the browsers history. Before I did that I had to hit back twice to get back to the angular page.

Note This hasn't been tested with IE8 yet. I'm going to do that now and see how it fairs.

Update Ok I just tested this in IE8 and I got stuck in a redirect loop. I've updated the code to have a simple variable to check if we've redirected. Seems to work. I'd love to know a prettier way.

like image 99
kristian Avatar answered Oct 12 '22 12:10

kristian