Christopher Nelson
Christopher Nelson

Reputation: 1017

Understanding this AngularJS directive?

I have a directive that is currently working to change a HTML class element after you've scrolled passed a part of the page. I've essentially just hacked the code together from what I found on the internet and I am having trouble understanding why or how it is working. I know if I can understand it better I can attempt to recreate it for more meaningful aspects of my project. I would appreciate any insight someone could give. Below is the Angular part:

myApp.directive('changeClassOnScroll', function ($window) {
return {
    restrict: 'A',   // What does this line do?
    scope: {
        offset: "@",   // A bit confused here
        scrollClass: "@"   // a bit confused here
    },
    link: function(scope, element) {
        angular.element($window).bind("scroll", function() { // understood
            if (this.pageYOffset >= parseInt(scope.offset)) { // understood
                element.removeClass(scope.scrollClass); // understood
                console.log('Scrolled below header.');
            } else {
                element.addClass(scope.scrollClass); // understood
            }
        });
      }
   };
})

In the HTML;

<nav change-class-on-scroll offset="100" scroll-class="navbar-transparent" class="navbar">
<!-- Don't understand why this works at all since these two elements are
<!-- not the same names as the function above? How does the directive
<!-- know to look for 'scroll-class' even tho in the directive it is
<!-- 'scrollClass' ?

Any help would really be much appreciated as to what is going on with it.

Upvotes: 1

Views: 81

Answers (3)

Muhammed Anees
Muhammed Anees

Reputation: 1850

From the documentation

At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform the DOM element and its children.

What you wrote is a standard angularjs code to create a custom directive that adds some functionalities to your dom.

restrict: 'A', // What does this line do?

'A' stands for attribute. Which means you can use this as an attribute of an html element like you used for your nav. You can use any of the following restrictions in a directive.

A - Attribute => <div change-class-on-scroll></div>

C - Class     =>  <div class="change-class-on-scroll"></div>

E - Element   =>  <change-class-on-scroll data="book_data"></change-class-on-scroll>

M - Comment   => <!--directive:change-class-on-scroll --><br/>

scope: {
offset: "@", // A bit confused here
scrollClass: "@" // a bit confused here
},

'@' is used here to bind the data from your html to directives scope. With offset="100", you are making the value 100 to be available in the directives scope, and then when you call scope.offset in your link function, you'll get the value. You can use '@', '=' or '&' to bind values to the directive based on whether it is a definite value, model data or a function.

why scroll-class when in directive it is scrollClass

It works because that's how it should be. By Angularjs naming convention, the directive name and the scope objects to bind should be in camel case in your js and should be written using dashes in your html.

Upvotes: 2

Shailesh Tanwar
Shailesh Tanwar

Reputation: 124

There are Four types of directive elements (E), attributes (A), class names (C), and comments (M).A directive can specify which of the 4 matching types it supports in the restrict property of the directive definition object.

'@' is used to pass simple values in a directive.

In Html we cannot use camel case. Therefor we use snake case instead of camel case. Hence scrollClass will be written as scroll-class.

Upvotes: 0

Edison Augusthy
Edison Augusthy

Reputation: 1573

restrict: 'A', // this will restrict directive only as attribute(you can only use it as attribute or it defines directive type)
scope: {
    offset: "@", // @ means that the changes from the controller scope will be reflected in the directive scope but if you modify the value in the directive scope, the controller scope variable will not get affected.
    scrollClass: "@" 
},

Upvotes: 0

Related Questions