在其他指令中重用angular指令

时间:2013-05-06 13:55:07

标签: javascript angularjs angularjs-directive

我想延迟加载图片和iframe(例如,一旦元素在视口中,就设置src)。我有一个现有的角度指令is-visible,它在元素滚动到视图时设置is-visible属性。如何在set-src-when-visible指令中重用此指令?

即,我希望此代码重用is-visible指令:

<img set-src-when-visible="http://example.com/img.png" />`
<iframe set-src-when-visible="http://example.com/" /> 

不满意的方法1:需要is-visible指令

我可以要求is-visible指令与我在set-src-when-visible指令上声明的相同元素:

<img set-src-when-visible="url" is-visible />

myApp.directive('setSrcWhenVisible', function () {
    return {
        restrict: 'A',
        require: 'isVisible',
        link: function ($scope, element, attrs) {
            var set = false;
            attrs.$observe('isVisible', function(isVisible) {
                if(isVisible && !set) {
                    attrs.$set('src', $scope.$eval(attrs.setSrcWhenVisible));
                    set = true;
                }
            });
        }
    }
});

以下是一个工作示例:http://jsfiddle.net/pvtpenguin/6tCk6/

缺点:我希望在重用set-src-when-visible时只能指定is-visible指令。


不满意的方法2:

创建两个指令,一个用于iframe,一个用于img标记:

<iframe set-iframe-src-when-visible="url"></iframe>
<img set-img-src-when-visible="url" />

angular.forEach(['Iframe', 'Img'], function(tagName) {
    var directiveName = 'set' + tagName + 'SrcWhenVisible';
    myApp.directive(directiveName, function ($window) {
        return {
            restrict: 'A',
            template: '<' + tagName + ' is-visible></' + tagName + '>',
            replace: true,
            link: function ($scope, element, attrs) {
                var set = false;
                attrs.$observe('isVisible', function(value) {
                    if(value && !set) {
                        attrs.$set('src', $scope.$eval(attrs[directiveName]));
                        set = true;
                    }
                });
            }
        }
    });
});

工作示例:http://jsfiddle.net/pvtpenguin/K4JuC/2/

下行:每个指令的名称不同,加上这与我用于声明和配置我的应用的方法不相符。

1 个答案:

答案 0 :(得分:1)

根据我们的评论讨论,这里有一个链接功能,希望能够做你想做的事情:

link: function ($scope, element, attrs) {
   $scope.src = attrs.setSrcWhenVisible;  // save attribute -- is $eval needed?
   var tagName = element[0].tagName;
   if(tagName == 'IMG') {
      var jqLiteWrappedElement = angular.element('<img is-visible></img>');
   } else {
      var jqLiteWrappedElement = angular.element('<iframe is-visible></iframe>');
   }
   element.replaceWith(jqLiteWrappedElement);
   $compile(jqLiteWrappedElement)($scope);
   var set = false;
   attrs.$observe('isVisible', function(value) {
      if(value && !set) {
         attrs.$set('src', $scope.src);
         set = true;
      }
   });
}

Fiddle