28

次の(非常に単純な)データ構造があるとしましょう:

$scope.accounts = [{
   percent: 30,
   name: "Checking"},
 { percent: 70,
   name: "Savings"}];

次に、フォームの一部として次の構造があります。

<div ng-repeat="account in accounts">
    <input type="number" max="100" min="0" ng-model="account.percent" />
    <input type="text" ng-model="account.name" />
</div>

ここで、各アカウント セットのパーセントの合計が 100 になることを検証したいと思いますが、これまでに見たカスタム ディレクティブの例のほとんどは、個々の値の検証のみを扱っています。一度に複数の依存フィールドを検証するディレクティブを作成する慣用的な方法は何ですか? jqueryにはこれに対するかなりの量の解決策がありますが、Angularの適切なソースを見つけることができませんでした.

編集:次のカスタムディレクティブを思いつきました(「共有」は元のコードの「パーセント」と同義です)。share-validate ディレクティブは、フォームのマップを"{group: accounts, id: $index}"値として受け取ります。

app.directive('shareValidate', function() {
return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, elem, attr, ctrl) {
        ctrl.$parsers.unshift(function(viewValue) {
            params = angular.copy(scope.$eval(attr.shareValidate));
            params.group.splice(params.id, 1);
            var sum = +viewValue;
            angular.forEach(params.group, function(entity, index) {
                sum += +(entity.share);
            });
            ctrl.$setValidity('share', sum === 100);
            return viewValue;
        });
    }
};
});

このALMOSTは機能しますが、フィールドが無効化された場合を処理できませんが、その後別のフィールドを変更すると再び有効になります。例えば:

Field 1: 61
Field 2: 52

フィールド 2 を 39 まで下げると、フィールド 2 は有効になりますが、フィールド 1 はまだ無効です。アイデア?

4

5 に答える 5

15

わかりました、次のように動作します (繰り返しますが、「共有」は「パーセント」です)。

app.directive('shareValidate', function () {
return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, elem, attr, ctrl) {
        scope.$watch(attr.shareValidate, function(newArr, oldArr) {
            var sum = 0;
            angular.forEach(newArr, function(entity, i) {
                sum += entity.share;
            });
            if (sum === 100) {
                ctrl.$setValidity('share', true);
                scope.path.offers.invalidShares = false;
            }
            else {
                ctrl.$setValidity('share', false);
                scope.path.offers.invalidShares = true;
            }
        }, true); //enable deep dirty checking
    }
};
});

HTML で、属性を「share-validate」に設定し、値を監視するオブジェクトのセットに設定します。

于 2013-09-08T16:46:17.380 に答える
5

フォームに可変数の入力フィールドを持つことができる動的フォームがあり、追加する入力コントロールの数を制限する必要がありました。

これらの入力フィールドは他の要因の組み合わせによって生成されるため、簡単に追加を制限することはできませんでした。そのため、入力フィールドの数が制限を超えた場合はフォームを無効にする必要がありました。controller でフォームへの参照を作成することでこれを行いctrl.myForm、入力コントロールが (コントローラー コードで) 動的に生成されるたびに、制限チェックを行い、次のようにフォームの有効性を設定します。ctrl.myForm.$setValidity("maxCount", false);

検証は特定の入力フィールドではなく、入力の総数によって決定されるため、これはうまく機能しました。複数のフィールドの組み合わせによって決定される、実行する必要がある検証がある場合、この同じアプローチが機能する可能性があります。

于 2015-11-10T22:24:46.003 に答える