2014-12-31 13 views
8

サービスを呼び出す非同期バリデーターは、メッセージとともに200(OK)または400(BadRequest)を返します。AngularJS非同期バリデーター - サーバーの応答からのUI検証メッセージ

メッセージを検証メッセージとして返信したいが、メッセージを表示する方法を理解できない。私は成功なしでいくつかのことを試みました。ここで

<div ng-messages="searchFilterForm.search.$error"> 
    <small ng-message="valid">Invalid search filter. Reason: {{MY_BAD_REQUEST_RESPONSE_MESSAGE_GOES_HERE}}</small> 
</div> 
+0

どのように非同期を設定しますかバリデーション、バリデーター – dfsq

+1

私が持っていたのとまったく同じ質問です。未回答のまま残っていましたが、何も組み込みませんでしたので、私はハックしました。今回はエキスパートから回答が得られるかどうか確認してください – harishr

+0

@dsfq、それは問題ではありませんが、ここに私のバリデーターへのリンクがあります:https://github.com/exceptionless/Exceptionless.UI/blob/master/src/ components/validators/search-filter-validator.jsとマークアップへのリンクhttps://github.com/exceptionless/Exceptionless.UI/blob/master/src/components/search-filter/search-filter-directive.tpl .html#L10-L26 –

答えて

0

はjsfiddleです:http://jsfiddle.net/javajunkie314/r6oyLe26/3/

アイデアがmyValidatormyErrorMessageディレクティブはmyErrorHandlerディレクティブを経由して、そのエラーメッセージを同期させることです。うーん、私はrejectに渡された理由にバリデーターでアクセスする方法を見つけることができません。

編集:私はフィドルを更新しました。現在、myValidatorは2つの非同期バリデータを使用しています。また、コントローラmyErrorHandlerの更新を処理するためにValidatorPromiseを作成しました。これは私のコメントで説明したとおりです。

HTML:

<form ng-controller="testCtrl"> 
    <div my-error-handler=""> 
     <input type="text" name="foo" ng-model="foo.text" my-validator=""> 
     <div my-error-message=""></div> 
    </div> 
</form> 

はJavaScript:

(function() { 
    var app = angular.module('myApp', []); 

    /* Wraps a promise. Used to update the errorHandler controller when the 
    * validator resolves. */ 
    app.factory('ValidatorPromise', function ($q) { 
     return function (errorHandler, name, promise) { 
      return promise.then(
       // Success 
       function (value) { 
        // No error message for success. 
        delete errorHandler.error[name]; 
        return value; 
       }, 
       // Failure 
       function (value) { 
        // Set the error message for failure. 
        errorHandler.error[name] = value; 
        return $q.reject(value); 
       } 
      ); 
     }; 
    }); 

    app.controller('testCtrl', function ($scope) { 
     $scope.foo = { 
      text: '' 
     }; 
    }); 

    app.directive('myErrorHandler', function() { 
     return { 
      controller: function() { 
       this.error = {}; 
      } 
     }; 
    }); 

    app.directive('myValidator', function ($timeout, $q, ValidatorPromise) { 
     return { 
      require: ['ngModel', '^myErrorHandler'], 
      link: function (scope, element, attrs, controllers) { 
       var ngModel = controllers[0]; 
       var myErrorHandler = controllers[1]; 

       ngModel.$asyncValidators.test1 = function() { 
        return ValidatorPromise(
         myErrorHandler, 'test1', 
         $timeout(function() {}, 1000).then(function() { 
          return $q.reject('Fail 1!'); 
         }) 
        ); 
       }; 

       ngModel.$asyncValidators.test2 = function() { 
        return ValidatorPromise(
         myErrorHandler, 'test2', 
         $timeout(function() {}, 2000).then(function() { 
          return $q.reject('Fail 2!'); 
         }) 
        ); 
       }; 
      } 
     }; 
    }); 

    app.directive('myErrorMessage', function() { 
     return { 
      require: '^myErrorHandler', 
      link: function (scope, element, attrs, myErrorHandler) { 
       scope.error = myErrorHandler.error; 
      }, 
      /* This template could use ngMessages to display the errors 
      * nicely. */ 
      template: 'Error: {{error}}' 
     }; 
    }); 
})(); 
+1

エラーメッセージを同期させるための指令ではなく、共有サービスを使用する方がより寛容であるかもしれません。 –

+0

あなたのソリューションを投稿していただきありがとうございますが、このようにすることも悪い考えです...コントローラ配列のmyErrorHandlerの後ろにngModelが渡されたらどうなりますか?複数の非同期バリデータがある場合はどうなりますか?余分なコードの量がちょうど上がった。 –

+0

'controllers'配列は' require'配列と同じ順序で渡されるので、心配する必要はありません。複数のバリデータに関しては、 '$ error'が' NgModelController'で動作するように、単一の文字列の代わりにエラーメッセージのオブジェクトを保持することができます。 –

0

私は私はあなたがやりたいと思うplunkerを用意しました。それはui-validateの修正版を使用していますが、あなたはとにかくそのアイデアを得ることができると思います。

私は 'remoteValidator'と呼ばれるサービスを定義しました。それは値が「悪い」場合メッセージを拒否する約束を返すサーバへの旅行をシミュレートするメソッド「validate」を持っています。

app.service("remoteValidator", function($q, $timeout) { 
    this.validate = function(value) { 
    return $q(function(resolve, reject) { 
     setTimeout(function() { 
     if (value === "bad") { 
      reject("Value is bad"); 
     } else { 
      resolve(); 
     } 
     }, 1000); 
    }); 
    } 
}); 

それから私は、コントローラにそのサービスを使用してバリデータを定義し、エラーメッセージをキャプチャし、お好みのバリデータに順番に約束を返すには、作業を行います。

$scope.remoteValAsync = function(value) { 
    var promise = remoteValidator.validate(value); 
    promise.then(function() { 
     delete $scope.errorMsg; 
    }, function(error) { 
     $scope.errorMsg = error; 
    }); 
    return promise; 
    }; 

この方法で、あなたは非同期入力ボックスに「不良」の書き込み、約束は解決したときに、エラーメッセージがform.field。$エラーリスト内のバリデータの名前とともにスコープに表示されます。

HTMLの抜粋:私は 'errorMsg内容' でメッセージをdroping知っ

<div class="input-group-inline"> 
    <input class="form-control" type="text" name="nextPassword" ng-model="passwordForm.nextPassword" 
      ui-validate-async="{ badValue: 'remoteValAsync($value)' }" /> 
     <p>Pending validations:</p> 
      <ul> 
      <li ng-repeat="(key, errors) in myForm.nextPassword.$pending track by $index">{{ key }}</li> 
      </ul> 
     <p>Bad validations:</p> 
      <ul> 
      <li ng-repeat="(key, errors) in myForm.nextPassword.$error track by $index">{{ key }}</li> 
      </ul> 
     <p>{{ errorMsg }}</p> 
</div> 

は最高ではありません。それはより良いことができますが、私はui-validate-async指令に入る必要があります。

私はそれが役に立ちそうです。

1

私はそれ以外の場合は値

json.put("success", true); 
json.put("values",output); 

で真として成功を収めてJSONを送信エラーが発生した場合、サーバー側 に取り扱うグローバルな例外は、エラーメッセージ

json.put("success", false); 
json.put("message",errorMessage); 

と偽として成功を送ってくださいお勧めします次に、UI側で例外処理を使用

$.post(serverUrl,valuesJson) 
.success(function(responseData) { 
    var responseData = JSON.parse(responseData); 
    if(responseData.success){ 
     \\ write your logic 
    } else { 
     alert(responseData.message); 
    } 
}).fail(function(xhr, textStatus, errorThrown) { 
    //check for session out 
    if(xhr.status == 403) 
     alert("Your session is timed out.redirected to Login screen."); 
    // redirect to login  
}) 
.error(function(responseData){ 
    console.log(responseData); 
}); 
関連する問題