Ir al contenido principal

AngularJS: Directive

Directive

Register directive with reserved word "directive"

Simple Directive




app.directive('myDirective', function($compile) {
return {
restrict: 'E',
link : function(scope, element, attrs, controller) {
var markup = "<input type='text' ng-model='test' /> {{test}} <br/>";
angular.element(element).html(markup);
$compile(element.contents())(scope);
}
};
});

Include Directive 

  • To add the directive Angular is Camel sensitive
  • In the html include the directive in a tag

HTML

<my-directive/>


Include Directive 

  • The elements for a directive can be:
    • E - element
    • A- attribute
    • C-class
    • M - comments


app.directive('myDirective', function($compile) {
return {
restrict: 'E',
template: "<input type='text' ng-model='test' /> {{test}} <br/>"
};
});


HTML

<my-directive/>

Include Directive as class

  • In this way you can repeat the directive many times
app.directive('myDirective', function($compile) {
return {
restrict: 'C',
template: "<input type='text' ng-model='test' /> {{test}} <br/>"
};
});
  • Add in HTML

HTML

<div class="role"></div>


Include Directive as HTML & avoiding a specific tag


app.directive('role', function(){
     
      return {
      restrict: 'E',
      replace: false,
      templateUrl : '/html/service/directives/case.html'

      }
     
});


Directive with own Scope

  • The scope apply only for the directive
app.directive('myDirective', function($compile) {
return {
restrict: 'C',
templateUrl: "/js/template/directive1.js",
scope: {
}
};
});
HTML
<div  class='my-directive'></div>
<div  class='my-directive'></div>
<div  class='my-directive'></div>


Directive with own Scope passing parameters 

  • Directive
app.directive('myDirective', function($compile) {
return {
restrict: 'E',
templateUrl: "/js/template/directive1.js",
scope: {
dirAttribute: "=myAttribute"
}
};
});
  • Template

<input type='text' ng-model='dirAttribute' /> {{dirAttribute}} <br/>
  • HTML
<my-directive my-attribute="message" />
  • Also can be use to bind 
    • @ (pass as a string)
    • = (pass as a integer)
    • &


Directive with own Scope passing FUNCTIONS (Isolate scope)

  • Controller
p.directive('myDirective', function($compile) {
return {
restrict: 'E',
  • Directive
  • To associate function should use &
app.directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
templateUrl: "/js/template/directive1.html",
scope: {
upvote: "&"
}
};
});
  • Template
<div>
<input type='text' ng-model='dirAttribute' /> {{dirAttribute}} <br>
<div ng-click="upvote()">Isolate</div>
<br />
</div>
  • HTML
<my-directive  upvote="click()"/>


    Directive to react with changes using observe

    • Directive
    app.directive('myDirective', function() {
    return {
    restrict: 'E',
            template: '<img />',
            replace: true,
            link: function(scope, element, attrs, controller) {
                attrs.$observe('attr', function(newValue, oldValue) {
                console.log(newValue);
                });
            }
    };
    });
    • HTML
    • When you type a new value in the input the directive will detect
    <div>
    <input type='text' ng-model='message' /> {{message}} <br />
    </div>
    <my-directive attr="{{message}}" />


    Directive with his own Controller

    app.directive('showTab', function () {
        return {
            restict: 'E',
            replace: true,
            template: "<button ng-click='sayHello()'></button>",
             controller: function($scope {
           $scope.sayHello = function(){
           alert('Hello');
     }
    
        };
    });
    • HTML
    <showTab/>


    Directive with External Controller

    app.directive('showTab', function () {
        return {
            restict: 'E',
            replace: true,
            template: "<button ng-click='sayHello()'></button>",
             controller: '@',
             name: 'ctrl'
     }
    
        };
    });

    • HTML
    <showTab ctrl="MyController"/>

    • Controller

    .app.controller('MyController', .....

    Associate directives inside other directives

    app.directive('myDirective', function() {
    return {
    restrict: 'E',
    replace: true,
    template: "<button ng-click='message()'>Adding a message </button>",
            controller: function($scope){
            var array = ['m1'];
            
            $scope.message = function(){
            alert(array.join() );
            }
            this.addingMessage = function(newMessage){
            array.push(newMessage);
            }        
            }
    };
    }).directive('extraMessage', function() {
    return{
    restrict: 'A',
    require: 'myDirective',
    link: function(scope, element, attrs, controller){
    controller.addingMessage('m2');
    }
    }).directive('extraMessage2', function() {
    return{
    restrict: 'A',
    require: 'myDirective',
    link: function(scope, element, attrs, controller){
    controller.addingMessage('m3');
    }
    }
    });

    • HTML
    <my-directive extra-message />



    Associate directives inside other directives with priority

    • Use priority to specify the order
    • Use terminal to avoid other directives with lower priority 

    
    
    app.directive('myDirective', function() {
    return {
    restrict: 'E',
    replace: true,
    priority: 1,
    templateUrl: "/js/template/directive1.html",
            controller: function($scope){
            var array = ['m1'];
            $scope.message = function(){
            alert(array.join() );
            }
            this.addingMessage = function(newMessage){
            array.push(newMessage);
            }
            
            }
    };
    }).directive('extraMessage', function() {
    return{
    restrict: 'A',
    priority: 1,
    terminal: false,
    require: 'myDirective',
    link: function(scope, element, attrs, controller){
    controller.addingMessage('m2');
    }
    }
    }).directive('extraMessage2', function() {
    return{
    restrict: 'A',
    priority: 2,
    require: 'myDirective',
    link: function(scope, element, attrs, controller){
    controller.addingMessage('m3');
    }
    }
    });

    • HTML
    <my-directive extra-message2 extra-message />


    Nesting Directives

    • Add ^ to consider the nested directive
    • Add transclude in the main directive 
      transclude: true,
    • In the template add ng-transclude inside a <div>

    app.directive('myDirective', function() {
    return {
    restrict: 'E',
    replace: true,
    transclude: true,
    templateUrl: "/js/template/directive1.html",
            controller: function($scope){
            var array = ['m1'];
            $scope.message = function(){
            alert(array.join() );
            }
            this.addingMessage = function(newMessage){
            array.push(newMessage);
            }
            }
    };
    }).directive('extraMessage', function() {
    return{
    restrict: 'A',
    require: '^myDirective',
    link: function(scope, element, attrs, controller){
    controller.addingMessage('m2');
    }
    }
    }).directive('extraMessage2', function() {
    return{
    restrict: 'A',
    require: '^myDirective',
    link: function(scope, element, attrs, controller){
    controller.addingMessage('m3');
    }
    }
    });

    • HTML
    <my-directive> 
    <div extra-message extra-message2 />
    </my-directive> 

    • Template
    <div>
    <button ng-click='message()'>Adding a message </button>
    <div ng-transclude></div>
    </div>



    Transclude

    This directive add external content to the Directive

    app.directive('collapse', function() {
    return {
    restrict: 'E',
    replace: true,
    templateUrl: "/js/template/directive2.html",
    transclude: true,
    scope:{
    message: '@'
    }
    };
    });

    • HTML
    <collapse message="{{message}}">
    <p> including external message</p>
    </collapse>

    • Template
    <div>
    <h3>{{message}}</h3>
    <div ng-transclude></div>
    </div>


    Directive using compile

    This example is an input that accept a text to be repeated 5 times inside in a directive

    • HTML
    <input type="text" ng-model="num">
    <div repeat-x="5">{{num}}</div>

    • Returning a scope
    app.directive('repeatX', function($compile) {
    return {
    link: function(scope, element, attributes, controller){
    for(var i=1; i< Number(attributes.repeatX); i++){
    element.after($compile(element.clone().attr('repeat-X', 0)) (scope));
    }
    }
    };
    });
    • Efficient way
    • In this case the scope is individual
    app.directive('repeatX', function($compile) {
    return {
    compile: function( element, attributes){
    for(var i=1; i< Number(attributes.repeatX); i++){
    element.after(element.clone().attr('repeat-X', 0));
    }
    }
    };
    });


    • Returning a link function
    app.directive('repeatX', function($compile) {
    return {
    compile : function(element, attributes) {
    for (var i = 1; i < Number(attributes.repeatX); i++) {
    element.after(element.clone().attr('repeat-X', 0));
    }
    return function(scope, element, attributes, controller) {
    attributes.$observe('text', function(newValue) {
    if (newValue === 'change') {
    element.css('color', 'red');
    }
    })
    }
    }
    };
    });

    • HTML
    <input type="text" ng-model="num">
    <div repeat-x="5" text='{{num}}'>{{num}}</div>

    AngularJS & JQuery


    • Add Jquery in the easiest way
      • Add the event to the element

    • HTML
    <input id="event" type="text">
    <script type="text/javascript">
    $('#event').datepicker();
    </script>


    Directive executing JQuery

    app.directive('datePicker', function($compile) {
    return {
    restrict: 'A',
    link: function(scope, element){
    element.datepicker();
    }
    };
    });

    • HTML
    <div>
    <input id="event" date-picker type="text">
    </div>













    app.directive('showTab', function () {
        return {
            link: function (scope, element, attrs) {
                element.click(function (e) {
                    e.preventDefault();
                    jQuery(element).tab('show');
                });
            }
        };
    });
    
    <a show-tab href="#tab_1">
        Tab 1
    </a>






    Comentarios