为验证图像url编写指令

时间:2013-01-13 16:18:58

标签: angularjs

这是我为AngularJS撰写的第一个指令。 我想检查插入文本输入的图像URL是否有效。

这是我到目前为止所做的:

angular.module('directives', [])
.directive('imageUrlVerify', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ctrl) {
            var image = new Image();

            scope.$watch(function() {
                if (ctrl.$viewValue) {
                    image.src = ctrl.$viewValue;

                    if (image.complete) {
                        scope[attrs.imageValid] = true;
                    } else {
                        scope[attrs.imageValid] = false;
                    }
                } else {
                    scope[attrs.imageValid] = false;
                }
            });
        }
    }
})

我用它:

<input type="text" ng-model="imageUrl" placeholder="Image URL..." data-image-valid="imageOk" image-url-verify>

这实际上是有效的,但作为我的第一个指示,我想确保我正确地做事......

我错过了什么吗?

编辑:关注@Josh-David-Miller的回答我想出了这个:

angular.module('directives', [])
.directive('imageUrlVerify', function() {
    return {
        restrict: 'A',
        replace: true,
        scope: { url: '=', imageValid: '=' },
        template: '<input ng-model="url" placeholder="Image URL..."/>',
        link: function(scope, element, attrs) {
            var image = new Image();

            scope.$watch('url', function() {
                scope.imageValid = false;
            });

            element.on( 'blur', function() {
                image.src = scope.url;
            });

            image.onload = function() {
                scope.$apply(function() {
                    scope.imageValid = true;
                });
            };

            image.onerror = function() {
                scope.$apply(function() {
                    scope.imageValid = false;
                });
            };
        }
    }
})

并使用它:

<input image-url-verify url="imageUrl" image-valid="imageOk" />

它看起来更好吗?在其他任何地方改进?

1 个答案:

答案 0 :(得分:1)

我不确定我是否遵循了您的指令,但可以稍微清理一下。

首先,可重复使用的指令应该具有隔离范围,因此它们不能弄乱它们不应该使用的任何东西。在您的情况下,它实际上使代码更简单。

其次,$ watch语句没有看任何东西。 $ watch接受第一个参数,该参数是要针对当前范围评估的字符串表达式,以及要使用每个摘要执行以确定值是否更改的方法。你的方法没有返回任何东西,所以没有什么值得关注的。您的代码实际上只是在每个摘要上执行相同的代码。也许你可以详细说明你的目标。

最后,每次按键都会进行验证,这可能不是很有帮助。当焦点离开输入元素时,我将其更改为运行。

这是更新后的代码:

angular.module('directives', [])
.directive('imageUrlVerify', function() {
  return {
    restrict: 'A',
    replace: true,
    scope: { url: '=', imageValid: '=' },
    template: '<input ng-bind="url" placeholder="Image URL..." valid="imageValid" />',
    link: function(scope, element, attrs) {
      var image = new Image();

      element.on( 'blur', function() {
        image.src = url;
        imageValid = url != "" && image.complete ? true : false;
      });
    }
  }
})

然后它的用法改为:

<input image-url-verify url="imageUrl" image-valid="imageOk" />

其中一些设计选择是首选项,有些将取决于您的具体用法,但缺少任何一个,这就是我重写您的指令的方式。