1

自分で読んでチェックしたことから、AngularJS + カスタム検証についていくつか疑問があります。

  • AngularJS は、単純なフィールド検証 (ng-require など) のための優れたヘルパーを提供します。
  • 単一フィールドのカスタム検証を実装する最良の方法は、ディレクティブを使用することです (コントローラーを汚染しません)。

複数のファイルに影響を与えるカスタムのビジネス検証がある場合、私の疑問が生じます。次の簡単なシナリオを確認してみましょう。

シンプルなUIの飛行状況

  • フライトの到着状況、フィールドを編集しています: 状況 (着陸/予定/遅延)、コメント (フライト状況に関する追加情報)。
  • 適用したいビジネス検証は次のとおりです。コメント フィールドは、ステータス フィールドの値が「遅延」の場合にのみ必要です。

    私がそれを実装した方法:

ディレクティブ + サービス

  • ステータス + コメント フィールドの変更を処理するディレクティブを定義します ($watch によるステータス)。
  • このディレクティブは、ビジネス検証をサービスに委任します

    このアプローチが私に与えていると思う利点は次のとおりです。

  • ビジネス サービスの検証が分離されます。

  • そのビジネス検証に単体テストを簡単に追加できます。

  • 再利用でき、UI 要素に依存しません。

    このサンプルを JSFiddle ( JSFiddle 検証サンプル) にコンパイルしました。

JS:


function MyCtrl($scope) {    
    $scope.arrival = {
        "id": 1,
        "originAirport": "Malaga (AGP)",
        "flightNumber": "Iberia 132",
        "dueAt": "2013-05-26T12:10:10",
        "status": 2,
        "info": "test"
    }
}


myApp.directive('validateinfofield', ['formArrivalValidation', function (formArrivalValidation) {
    return {
        require: "ngModel",
        link: function(scope, elm, attrs, ctrl) {


            ctrl.$parsers.unshift(function(viewValue){
                // Empty? Let's check status
                //if (!viewValue.length && scope.arrival.status == 3) {
                if(formArrivalValidation.validateInfoField(scope.arrival.status, viewValue)) {
                    ctrl.$setValidity('validInfo', true);
                } else {
                    ctrl.$setValidity('validInfo', false);
                }
            });

            // Let's add a watch to arrival.status if the values change we need to 
            // reevaluate, if comments is empty and status is delayes display error
            scope.$watch('arrival.status', function (newValue, oldValue) {
                if (formArrivalValidation.validateInfoField(newValue, scope.editArrivalForm.txInfo.$viewValue)) {
                    ctrl.$setValidity('validInfo', true);
                } else {
                    ctrl.$setValidity('validInfo', false);
                }
            });

        }
    };
}]);

// Validation Service, limited to our "business language"
myApp.factory('formArrivalValidation',

   function () {
       return {
           validateInfoField: function (status, infoField) {
               var isOk = true;

               if (status == 3) {
                   if (infoField == undefined) {
                       isOk = false;
                   } else {
                       if (!infoField.length)
                           isOk = false;
                   }
               }

               return isOk;
           },

       };
   });

これは従うべき良いアプローチですか?これを達成するためのより良い、より簡単な方法はありますか?

4

2 に答える 2

2

この部分について-「適用したいビジネス検証は次のとおりです。コメントフィールドは、ステータスフィールドの値が「遅延」の場合にのみ必要です。コメントフィールドセットの場合、ng-required = "flight.status == 'DELAYED'」"

于 2013-06-27T14:47:12.277 に答える
0

この質問に戻ります... 1 つの有効なアプローチは、パラメーターとして 2 番目の値を受け入れるディレクティブを作成することです (たとえば、コメントは空です)。

于 2014-02-09T16:39:39.013 に答える