0

これは、私が 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" />

それは良く見えますか?他に改善すべき点はありますか?

4

1 に答える 1

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" />

これらのデザインの選択肢の中には好みのものもあれば、特定の使用法に依存するものもありますが、どちらも存在しない場合、これが私があなたのディレクティブを書き直す方法です。

于 2013-01-13T20:05:06.140 に答える