Search code examples
jqueryangularjscontrollers

AngularJS Controller Issues - Click function stops working on page change


Hoping someone can help out an AngularJS noob!

I've set up a basic site with routing to change pages. All these pages have a persistent menu that interacts with the DOM to toggle classes on/off. The issue i'm having is that on initial page load, the click function works on the "Home" page, but when I navigate away to "Blog" the function stop working:

app.config(['$routeProvider', function ($routeProvider) {
  $routeProvider
    .when("/", {templateUrl: "partials/home.html", controller: "PageCtrl"})
    .when("/blog", {templateUrl: "partials/blog.html", controller: "PageCtrl"})
}]);

app.controller('PageCtrl', function (/* $scope, $location, $http */) {
  $('#works-navigation .navigation-label').click(function () {
    $('body').toggleClass('show-works-navigation');
  });
});

Any ideas?!


Solution

  • That jQuery listener is attached to a single element which disappears or gets refreshed when Angular navigates. Either use .on() listeners which work for dynamically added elements, or simply drop jQuery and do it the Angular-way.

    jQuery way with delegated handler :

    $("#works-navigation ").on("click", ".navigation-label", function() {
        $('body').toggleClass('show-works-navigation');
    });
    

    A more Angularized way

    This is easily done using a $rootScope variable (sWN in the example) to control the body class. So, for start, add ng-class to the body:

    <body ng-class="{'show-works-navigation': sWN}">
    

    Then on your .navigation-label element add ng-click:

    <div class="navigation-label" ng-click="$root.sWN = !$root.sWN"></div>
    

    This will flip the value of our rootScope variable sWN, which we use to trigger the body class.

    You can also do this without the rootScope, but since you're triggering a class on the body element, I think it's the safest way.