Thursday, May 2, 2013

Re-Usable Directive Base in AngularJS

This post describes one method for making a re-usable directive base in AngularJs.  There are other patterns than can be used to wrap this method.

I have to admit something about this feels wrong!  But it works.

Look for the RED  text in the code, this re-mapping of data is what makes this pattern work.  If you try using "this.someArg1" directly in the code...'undefined' error.

I would not use this 'pattern' if you are making a one off directive.  I am making directives for xml documents.  With 10 different xml nodes that all need the same base...I don't want to copy and paste that much code.

I'll show the usage first to add some context to the myFancyBase function. "p:" stands for person in a random xml example.

MyApp.directive('p:Name',['dependency1','dependency2',function(d1,d2){
    var fb = myFancyBase().getBase();
     fb.someArg1 = d1.foo;
     fb.someArg3 = 'whatever';
     return fb.getDirective();
}])

I've color coded things to give you a headache and to help match up instances of the same vars.

var myFancyBase = function(){

   var getBaseFn = function(){
            //This mapping just feels wrong
             var someArg1=this.someArg1,
             someArg2 =this.someArg2,
             someArg3=this.someArg3;

            var getDirectiveBaseFn = function(){
                          priority: 50,
                          replace: false,
                          transclude: false,
                          restrict: 'E',
                          scope: false,
                          link: function(scope, element, attrs) {
                             //special sauce for my fancy directive
                              var x= foo(someArg1);
                              var y = bar(x + someArg2);
                          }
                   }

        return{
            getDirectiveBase:getDirectiveBaseFn,
            someArg1:undefined,
            someArg2:'my default setting',
            someArg3:undefined
         };
    }

  return{
     getBase:getBaseFn
  };
}

No comments:

Post a Comment