Mohamed Hussain
Mohamed Hussain

Reputation: 7703

AngularJS issue: Directive not called on Second Page after Routing

I am developing an angular app,

I am binding angular directive mytoggle for toggle the content in the page, but the toggle is only working on the first page if I go to second page via angular routing, same directive is not called so the toggle is also not working.

I have created a gist, gist link url: https://gist.github.com/shmdhussain/c802c7a59c78d8e498da

Index.html:

<html xmlns:ng="http://angularjs.org" lang="en" id="ng-app" ng-app="myApp">
        <head>
            <meta charset="utf-8">
            <title>Angular App</title>
            <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.15/angular.min.js"></script>
            <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.15/angular-route.js"></script>
            <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

            <script src="app.js"></script>
            <script src="js/controllers/ctrl.js"></script>
            <style type="text/css">
                .show{display:none}
            </style>
        </head>
        <body>
            <div ng-controller="parentCtrl" class="">
                <div ng-view>
                </div>
            </div>
        </body>
    </html>

Default.html

<p><a href="#/p1">page 1</a></p>
<p><a href="#/p2">page 2</a></p>

Page1.html:

<div>
    <p mytoggle class="toggle">Toggle ME Page 1</p>
</div>

<div class="show">
    <p>In Page One</p>
    <p>In Page One</p>
    <p>In Page One</p>
    <p>In Page One</p>
    <p>In Page One</p>
    <p>In Page One</p>
    <p>In Page One</p>
    <p>In Page One</p>
</div>

Page2.html:

<div>
    <p mytoggle class="toggle">Toggle ME Page2</p>
</div>

<div class="show">
    <p>In Page Two</p>
    <p>In Page Two</p>
    <p>In Page Two</p>
    <p>In Page Two</p>
    <p>In Page Two</p>
    <p>In Page Two</p>

</div>

app.js:

// Create a new module
var myApp = angular.module('myApp', ['ngRoute']);

// register a new service
//myApp.value('appName', 'MyCoolApp');

// configure existing services inside initialization blocks.
myApp.config(function($locationProvider,$routeProvider) {
    $routeProvider

    .when('/p1', {
      templateUrl:'partials/page1.html'

    })
    .when('/p2', {
       templateUrl:'partials/page2.html'


    })
    .when('/default', {
      templateUrl:'partials/default.html'

    .otherwise({
      redirectTo:'/default'
    });



});

ctrl.js:

myApp.controller('parentCtrl',['$scope','$window','$location',function ($scope,$window,$location) {


}]);

myApp.directive('mytoggle',function(){
    console.log("inside dir");
    //ALERTS    
    jQuery(".toggle").click(function (e) { 
        console.log("ddd");
        console.log("class names: "+jQuery(e.target).attr('class'));
        jQuery(".show").slideToggle("slow");

    });
    return true;
});

Upvotes: 0

Views: 1378

Answers (1)

tasseKATT
tasseKATT

Reputation: 38490

myApp.directive('mytoggle', function() {

  // The injecting function of the directive.
  // Executed only once for the entire app (if the directive is used).
  console.log('Injecting function says hello.');

  // Simplest form of returning postLink function
  return function postLink() {

    // The postLink function of the directive.
    // Executed once per instance of the directive, each time it's rendered.
    console.log('postLink says hello.');

    jQuery(".toggle").click(function(e) {
      jQuery(".show").slideToggle("slow");
    });
  };
});

If you want to keep this as a directive I would at least recommend the following:

myApp.directive('mytoggle', function() {

  return {
    restrict: 'A',
    link: function postLink(scope, element, attrs) {

      var onClick = function() {
        $('.show').slideToggle("slow");
      };

      element.on('click', onClick);

      scope.$on('$destroy', function() {
        element.off('click', onClick);
      });
    }
  };
});

Upvotes: 1

Related Questions