1

form-validation-as-you-type のディレクティブを使用しています。ユーザー名フィールドが変更されるたびに、http 要求が行われます。リクエストが発生したことをコンソールで確認できますが、フィールドでぼかしイベントが発生するまで、ビューは「固有の」エラー メッセージで更新されません。

ただし、ユーザー名が重複したものから一意のものに変更されるとすぐに、エラー メッセージはすぐに消えます。この方向にはぼかしは必要なく (エラー メッセージを非表示)、もう一方の方向にのみぼかします (エラー メッセージを表示)...

何故ですか?

=======指令=========

myDirs.directive('ensureUnique', ['$http', function($http) {
return {
    require: 'ngModel',
    link: function(scope, ele, attrs, c) {  if (scope.registered) {return true};
        scope.$watch(attrs.ngModel, function() {
            $http({
                method: 'GET',
                url: 'http://webservice.buddyplatform.com/v1/UserAccount_Profile_CheckUserName',
                params: {
                    UserNameToVerify: ele.val(),
                    BuddyApplicationName:'xxx',
                    BuddyApplicationPassword:'yyy'
                }
            }).success(function(data, status, headers, cfg) {
                    c.$setValidity('unique', (data==='UserNameAvailble'));
                }).error(function(data, status, headers, cfg) {
                    c.$setValidity('unique', false);
                });
           });
        }
    }
}]);

=========== HTML ================

<label>Username:</label>
    <input name="username" type="text" ng-model="form.username" 
           ng-minlength=5 ng-maxlength=20 ensure-unique="username" required/>
    <div class="error" ng-show="myForm.username.$dirty && myForm.username.$invalid">
        <small class="error" ng-show="myForm.username.$error.required">Please input a username</small>
        <small class="error" ng-show="myForm.username.$error.minlength">Your username is required to be at least 5 characters</small>
        <small class="error" ng-show="myForm.username.$error.maxlength">Your username cannot be longer than 20 characters</small>
        <small class="error" ng-show="myForm.username.$error.unique">That username is taken, please try another</small>
    </div>
4

1 に答える 1

0

ダイジェスト サイクルは複雑ですが、私が理解しているように、成功はダイジェスト サイクル内にあり、その後に新しいダイジェスト サイクルはありません。したがって、有効性を設定しても、別のダイジェストが存在するわけではありません。これを回避するにはいくつかの方法があります。最も簡単な方法は、$timeoutサービスを使用することです。これを行うには、$timeoutディレクティブに挿入してから、次のようにコードを変更します。

$timeout(function(){c.$setValidity('unique', (data==='UserNameAvailble'));});

これは、$apply を使用するか、手動で $digest をトリガーすることによっても実行できます。ただし、位相がずれている場合、これらの方法はどちらもエラーを引き起こす可能性があります。$timeout は、必要がない場合でも、常に別のダイジェストをトリガーするため、それほど高速ではありません。ダイジェスト、サイクルなどに関連する質問がたくさんあります。これは特に関連性があります: Angular JS: Chaining promises and the digest cycle

于 2013-08-06T17:57:39.017 に答える