angular-responsive icon indicating copy to clipboard operation
angular-responsive copied to clipboard

Refactor directives to be more DRY

Open ThomasBurleson opened this issue 11 years ago • 0 comments

Really nice code library. I just wanted to suggest a refactor that could improve your code maintenance and reader understanding.

.directive('arMobile', ['responsiveHelper', function (responsiveHelper) 
{
    return {
        restrict    : "EAC",
        transclude  : 'element',
        template    : '<div></div>',
        compile     : buildCompileFn( 'arMobile', responsiveHelper.isMobile )
    };
}])
.directive('arMobile', ['responsiveHelper', function (responsiveHelper) 
{
    return {
        restrict    : "EAC",
        transclude  : 'element',
        template    : '<div></div>',
        compile     : buildCompileFn( 'arTablet', responsiveHelper.isTablet )
    };
}])
.directive('arMobile', ['responsiveHelper', function (responsiveHelper) 
{
    return {
        restrict    : "EAC",
        transclude  : 'element',
        template    : '<div></div>',
        compile     : buildCompileFn( 'arDesktop', responsiveHelper.isDesktop )
    };
}])
.directive('arResponsive', ['responsiveHelper', function (responsiveHelper) 
{
    return {
        restrict    : "EAC",
        transclude  : 'element',
        template    : '<div></div>',
        compile     : buildCompileFn( 'arResponsive', checkAllTypes(responsiveHelper) )
    };
}])

/**
 * Partial application for DRY construction of a directive compile function
 */
function buildCompileFn(responsiveType, verifyFn )
{
  return function (element, attr, transclude) 
  {
      return function postLink(scope, element, attr) 
      {
          var childElement, childScope,
          var deviceTypes = scope.$eval( attr[responsiveType] );

          scope.$watch( deviceTypes, function () 
          {
              // attribute changed, delete existing element & $scope

              if (childElement) {
                  childElement.remove();
                  childScope.$destroy();
                  childElement = undefined;
                  childScope = undefined;
              }

              if ( verifyFn(deviceTypes) ) 
              {
                  // Create a new element and $scope...

                  childScope = scope.$new();
                  childElement = transclude(childScope, function (clone) {
                      element.after(clone);
                  });
              }
          });
      };
  };
}

/**
 * Partial application for DRY construction of function to scan of any valid responsive types 
 */
function checkAllTypes(responsiveHelper)
{
    return function( deviceTypes )
    {
        return  ( deviceTypes['Mobile'] && responsiveHelper.isMobile() ) || 
                ( deviceTypes['Tablet'] && responsiveHelper.isTablet() ) || 
                ( deviceTypes['Desktop'] && responsiveHelper.isDesktop() );
    };
}

ThomasBurleson avatar Apr 25 '14 02:04 ThomasBurleson