当前位置: 动力学知识库 > 问答 > 编程问答 >

javascript - AngularJS directive not updating view as expected

问题描述:

I am using a directive for form-validation-as-you-type. An http request is made for every change of the username field. I can see in my console that the requests happen, but the view isn't updated with the "unique" error message until a blur event occurs for the field.

However, as soon as the username is changed from a duplicate to a unique one, the error message disappears instantly. No blur is needed going in this direction (hide error message), only in the other (display error message)...

Why is that?

======= Directive =========

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>

网友答案:

The digest cycle is tricky, but as I understand it, success is inside a digest cycle, there is no new digest cycle after. So setting the validity doesn't mean there will be another digest. There are a few ways to get around this. The easiest way is to use $timeout service. To do that, inject $timeout into your directive then change the code like so:

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

You can also do this with an $apply or by manually triggering a $digest. But both of those methods can trigger an error if you're out of phase. $timeout is not as fast because it ALWAYS triggers another digest, even if one isn't needed. There are a ton of questions related to digests, cycles, etc. This one is particularly relavent: Angular JS: Chaining promises and the digest cycle

分享给朋友:
您可能感兴趣的文章:
随机阅读: