user3574939
user3574939

Reputation: 829

angular directive $scope undefined

The code below has suddenly stopped working. I am receiving a console log error that $scope is undefined. When I pass $scope the console error is gone, but the code is still not working, however 'Page animated!' is displayed in the console window.

.directive('active', function(){
    return{
             link: function(scope, element, attrs){

                 $(element).on('click', function(){
                     console.log('Page animated!');

                     //addes class to animate page
                     $scope.elementClass = "my-slide-animation";            
          });
       }
    }
});

code with $scope passed

.directive('active', function(){
    return{
             link: function(scope, element, attrs){

                 $(element).on('click', function($scope){
                     console.log('Page animated!');

                     //addes class to animate page
                     $scope.elementClass = "my-slide-animation";            
          });
       }
    }
});

I've also tried the following:

1.

.directive('active', function($scope){
        return{
                 link: function(scope, element, attrs){

                     $(element).on('click', function($scope){
                         console.log('Page animated!');

                         //addes class to animate page
                         $scope.elementClass = "my-slide-animation";            
              });
           }
        }
    });

2.)

//ng-enter and ng-leave animation
.directive('active', function($scope){
    return{
             link: function($scope, element, attrs){

                 $(element).on('click', function($scope){
                     console.log('Page animated!');

                     //addes class to animate page
                     $scope.elementClass = "my-slide-animation";            
          });
       }
    }
});

3.

//ng-enter and ng-leave animation
.directive('active', function(){
    return{
             link: function(scope, element, attrs){

                 $(element).on('click', function(){
                     console.log('Page animated!');

                     //addes class to animate page
                     scope.elementClass = "my-slide-animation";         
          });
       }
    }
});

4.

//ng-enter and ng-leave animation
.directive('active', function(){
    return{
             link: function(scope, element, attrs){

                 $(element).on('click', function(scope){
                     console.log('Page animated!');

                     //addes class to animate page
                     scope.elementClass = "my-slide-animation";         
          });
       }
    }
});

complete app.js

 angular.module('myWebsite',['ngRoute', 'duScroll','ngAnimate','headroom'])
    .config(function($routeProvider){
        $routeProvider
            .when('/#', {
                templateUrl:'home.html'
                })
            .when('/about', {
                templateUrl:'about.html'
                })
            .when('/contact',{
                templateUrl:'contact.html'
                })
            .when('/services', {
                templateUrl:'services.html'
                })
            .otherwise({
                templateUrl:'home.html'
                });
    })

    .controller('mainCtrl', function($scope, $document)
    { 
    //enables angular-scroll.min.js with dependency of 'duScroll'
     $scope.toTheTop = function() {
          $document.scrollTopAnimated(0, 2000).then(function() {
            console && console.log('You just scrolled to the top!');
          })
        }       
    })

    //directive for jQuery nivoSlider plugin
    .directive('slideit', function(){
        return{
            link: function(scope, element, attrs){

            $(element).nivoSlider();

            }
        }
    })
    //ng-enter and ng-leave animation
    .directive('active', function(){
        return{
                 link: function(scope, element, attrs){
                  $(element).on('click', function(){
                  console.log('Page animated!');

                  //addes class to animate page
                  scope.elementClass = "my-slide-animation";

                  scope.$apply();
              });
           }
        }
    });

Upvotes: 1

Views: 437

Answers (4)

user3574939
user3574939

Reputation: 829

Ultimately, I decided to move the onclick function into my 'navigationController' and applied $rootScope to reference the $scope in the 'mainController'. I read in another post that $rootScope works similar to a global variable in JS and other programming languages; bad I know. I did check the console.log to see if the onclick event is firing when buttons other than the navigation buttons and they're not. :)

Although this approach is working, I am still open to suggestions on how to better resolve this task.

angular.module('myWebsite')
.controller('navigationController', ['$scope', '$location', '$element','$rootScope', function($scope, $location, $element, $rootScope){

    // adds class 'my-slide-animation' to ng-view when navigation buttons are clicked
            $element.on('click', function(){

            console.log('animation go!');

            $rootScope.elementClass = "my-slide-animation"; 
        }); 

    //adds class on current page navigation button 'bold'
    $scope.isCurrentPath = function(path)
    {
        return $location.path() == path; 
    };

}]);

Upvotes: 0

Pankaj Parkar
Pankaj Parkar

Reputation: 136134

In addition to above answers you need to apply scope inside event to run digest.

Code

.directive('active', function(){
    return{
             link: function(scope, element, attrs){
              element.on('click', function(){
              console.log('Page animated!');
              //addes class to animate page
              scope.elementClass = "my-slide-animation";
              scope.$apply(); //run digest cycle to update binding
          });
       }
    }
});

Upvotes: 0

mohamedrias
mohamedrias

Reputation: 18566

In your directive, the link function contains the scope as parameter.

So As per your link function, it's defined as scope. So you must refer $scope as scope.

So

$scope.elementClass = "my-slide-animation";            

will become

scope.elementClass = "my-slide-animation";            

Else, if you want to use $scope, then

In your Link function make the change

link: function($scope, element, attrs){

Also not, since you are updating the scope inside jQuery context, you may need to call scope.$apply(); in your directive code as well.

Upvotes: 0

tymeJV
tymeJV

Reputation: 104775

Because it's defined as scope, not $scope in your link function

link: function(scope, element, attrs){
              ^^^

scope.elementClass = "my-slide-animation";          

Upvotes: 4

Related Questions