Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular routing something weird happening

Tags:

html

angularjs

I am still learning angularjs so maybe there's something stupid I am not understanding but I have a really strange behaviour when using routing.

In my application I use the following code to define my routes:

var app = angular.module('app', []);
app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
  $routeProvider.
    when('/pneumatici/:chunka', {}).
    when('/pneumatici/:chunka/:chunkb', {});

  $locationProvider.html5Mode(true);
}]);

And in a controller I manage them this way:

app.controller('appCtrl', ['$scope', '$route', '$routeParams', '$location', function ($scope, $route, $routeParams, $location) {
  $scope.$on('$routeChangeSuccess', function (current,previous) {
    if (!($location.path().indexOf('/pneumatici') === -1)) {
      $scope.chunka = $route.current.params.chunka; $scope.chunkb = $route.current.params.chunkb;

      /** do my stuff with chunka and chunkb **/

    } else {
      window.location.href = $location.path();
    }
  });

I have no ngView, no template, nothing. It works like a charm.

Please note the line where I actually force a page load in case the url is not intended to be managed by the controller appCtrl. I was forced to do that because once I define my route to catch '$routeChangeSuccess' all links in the page when clicked are catched by angular and no page load occurs even if the link doesn't have the format defined with 'when'. I would have like to do it with 'otherwise' but I could not understand how to, if doable.

Now the problem. In the page of course I have links like just '/privacy.html', if I click them the page load is correctly triggered and I do see '/privacy.html' but unfortunately once there if I click the back button I can see the url of the browser changing to (let's say) /pneumatici/foo/bar but no page load is triggered.

Please note in the privacy.html page I have no angular routing defined, there's no .config no .when; there's an anagular app defined, with a controller, but no injection of '$routeProvider' anywhere, no definition of any route.

What is happening? What I am doing wrong?

Thanks for any help!

Update. I found a viable solution adding:

angular.element("a").prop("target", "_self");

Angular routing is ignored for all 'a' elements with 'target' set to "_self", didn't know that.

Still if I look at this strategy as a whole doesn't sound very elegant to me and I would love to improve it. What I don't like is since I am defining the route in .config I should be able to tell angular to skip any url which do not match the format/path I defined there.

But I don't know if that is doable or not, does anyone know out there?

like image 655
Max Favilli Avatar asked Mar 29 '13 13:03

Max Favilli


1 Answers

By turning on html5mode your app should be acting like it should intercept everything on the site by default (from '/'.)

From that perspective, it seems like $location.path() should work in your explicit override, but it isn't really correct ($location.url() would be) and the browser already has the correct URL, so maybe you can't force a reload with location.href = location.href in your specific browser.

Rather than going down that path, I would do the following to make it DRY:

If you add a base href:

<base href="/pneumatici/"></base>

and replace /pneumatici/ with / in your when clause(s):

$routeProvider.
    when('/:chunka', {}).
    when('/:chunka/:chunkb', {});

then you should just need this:

$scope.$on('$routeChangeSuccess', function (current,previous) {

    $scope.chunka = $route.current.params.chunka;
    $scope.chunkb = $route.current.params.chunkb;

  /** do my stuff with chunka and chunkb **/
});
like image 101
lossleader Avatar answered Sep 24 '22 19:09

lossleader