0

スコープ内の値を検証するカスタム ディレクティブを作成しています。これは必須属性のように機能するはずですが、入力テキストを検証する代わりに、スコープ内の値を検証します。私の問題は、この値が $scope.$watch 関数で設定され、この関数がディレクティブの後に実行されることです。したがって、ディレクティブが値を検証しようとすると、まだ設定されていません。カスタム ディレクティブを実行する前に $watch コードを実行することはできますか?

コードは次のとおりです。

var app = angular.module('angularjs-starter', []);

app.controller('MainCtrl', function($scope) {
  var keys = {
    a: {},
    b: {}
  };
  $scope.data = {};

  // I need to execute this before the directive below
  $scope.$watch('data.objectId', function(newValue) {
    $scope.data.object = keys[newValue];
  });
});

app.directive('requiredAttribute', function (){ 
   return {
      require: 'ngModel',
      link: function(scope, elem, attr, ngModel) {
          var requiredAttribute = attr.requiredAttribute;
          ngModel.$parsers.unshift(function (value) {
             ngModel.$setValidity('requiredAttribute', scope[attr.requiredAttribute] != null);
             return value;
          });
      }
   };
});

<input type="text" name="objectId" ng-model="data.objectId" required-attribute="object" />
<span class="invalid" ng-show="myForm.objectId.$error.requiredAttribute">Key "{{data.objectId}}" not found</span>

そして、ここにプランカーがあります:http://plnkr.co/edit/S2NrYj2AbxPqDrl5C8kQ?p=preview

ありがとう。

4

1 に答える 1

1

$watchディレクティブ リンク関数の前に直接発生するようにスケジュールできます。機能を変更する必要がありますlink

link: function(scope, elem, attr, ngModel) {
    var unwatch = scope.$watch(attr.requiredAttribute, function(requiredAttrValue) {
        if (requiredAttribute=== undefined) return;

        unwatch();

        ngModel.$parsers.unshift(function (value) {
            ngModel.$setValidity('requiredAttribute', requiredAttrValue != null);
            return value;
        });
    });
}

このアプローチは、ディレクティブ内の $watch 関数を一度だけアクティブにし、必要なスコープ変数が初めて設定されたときにウォッチャーを削除します。

値を解析してこの方法でチェックする別のアプローチもあります。

link: function(scope, elem, attr, ngModel) {
    var parsedAttr = $parse(attr.requiredAttribute);

    ngModel.$parsers.unshift(function (value) {
        ngModel.$setValidity('requiredAttribute', parsedAttr(scope) != null);
        return value;
    });
}

ここでは$parse AngularJS サービスを使用する必要があります。ここでの違いは、必要なスコープ変数に設定された最初の値を待たずに、入力フィールドを無効としてマークすることです。

どちらのバリアントでも、単純な変数名の代わりに式を渡すことができます。これにより、 として何かを書くことが可能になりますrequired-attribute="object.var1.var2"

それは本当にあなたが必要とするものに依存します.

于 2013-09-18T13:54:35.437 に答える