【发布时间】:2014-08-14 22:22:54
【问题描述】:
我创建了一个自定义验证指令并在表单中使用它。可以触发没有问题,但是触发validation之后,发现model值就丢失了。说我有
ng-model="project.key"
验证后,project.key 不再存在于范围内。我想我以某种方式理解 AngularJS 并做错了什么。
代码会说话。
这是我的html页面:
<div class="container">
...
<div class="form-group"
ng-class="{'has-error': form.key.$invalid && form.key.$dirty}">
<label for="key" class="col-sm-2 control-label">Key</label>
<div class="col-sm-10">
<input type="text" class="form-control text-uppercase" name="key"
ng-model="project.key" ng-model-options="{ debounce: 700 }"
placeholder="unique key used in url"
my-uniquekey="vcs.stream.isProjectKeyValid" required />
<div ng-messages="form.key.$error" ng-if="form.key.$dirty"
class="help-block">
<div ng-message="required">Project key is required.</div>
<div ng-message="loading">Checking if key is valid...</div>
<div ng-message="keyTaken">Project key already in use, please
use another one.</div>
</div>
</div>
</div>
<div class="col-sm-offset-5 col-sm-10">
<br> <a href="#/" class="btn">Cancel</a>
<button ng-click="save()" ng-disabled="form.$invalid"
class="btn btn-primary">Save</button>
<button ng-click="destroy()" ng-show="project.$key"
class="btn btn-danger">Delete</button>
</div>
</form>
这是我的指令:
.directive('myUniquekey', function($http) {
return {
restrict : 'A',
require : 'ngModel',
link : function(scope, elem, attrs, ctrl) {
var requestTypeValue = attrs.myUniquekey;
ctrl.$parsers.unshift(function(viewValue) {
// if (viewValue == undefined || viewValue == null
// || viewValue == "") {
// ctrl.$setValidity('required', false);
// } else {
// ctrl.$setValidity('required', true);
// }
setAsLoading(true);
setAsValid(false);
$http.get('/prism-cmti/2.1', {
params : {
requestType : requestTypeValue,
projectKey : viewValue.toUpperCase()
}
}).success(function(data) {
var isValid = data.isValid;
if (isValid) {
setAsLoading(false);
setAsValid(true);
} else {
setAsLoading(false);
setAsValid(false);
}
});
return viewValue;
});
function setAsLoading(bool) {
ctrl.$setValidity('loading', !bool);
}
function setAsValid(bool) {
ctrl.$setValidity('keyTaken', bool);
}
}
};
});
这是表单页面的控制器:
angular.module('psm3App').controller(
'ProjectCreateCtrl',
[ '$scope', '$http', '$routeParams', '$location',
function($scope, $http, $routeParams, $location) {
$scope.save = function() {
$http.post('/prism-cmti/2.1', {requestType:'vcs.stream.addProject', project:$scope.project})
.success(function(data) {
$location.path("/");
});
};
}]);
在这个错误之前,不知何故我也需要在我的自定义验证指令中处理所需的验证,如果我不这样做,所需的验证就会出错。现在想起来,可能这两个问题的根本原因是一样的:我的指令链接函数触发后模型值就没有了。
我正在使用 Angular1.3 Beta 18 BTW。
感谢任何帮助。提前致谢。
更新:
按照@ClarkPan 的回答,我立即将ctrl.$parsers.unshift() 中的代码更新为return viewValue,这使得required 验证现在运行良好,所以我不再需要下面的行了。
// if (viewValue == undefined || viewValue == null
// || viewValue == "") {
// ctrl.$setValidity('required', false);
// } else {
// ctrl.$setValidity('required', true);
// }
但是{{project.key}} 仍然没有得到更新。
然后我尝试在这里注释掉这两行:
setAsLoading(true);
setAsValid(false);
模型值{{project.key}} 已更新。我知道如果任何验证失败,模型值将被清除,但我认为
function(data) {
var isValid = data.isValid;
if (isValid) {
setAsLoading(false);
setAsValid(true);
} else {
setAsLoading(false);
setAsValid(false);
}
}
in $http.get(...).success() 应该在 $digest 循环中执行,这意味着模型值应该更新。
怎么了?
【问题讨论】:
-
我没有扫描你所有的代码,但是如果对某个字段的任何验证失败,关联的 ng-model 将被清除。通过创建
<input type="email" ng-model="input.something">和{{ input.something }}最容易看到这种行为。当输入不包含有效的电子邮件地址时,它将清除模型值。 -
@null,感谢您的快速回复。我知道如果验证失败,模型将不会更新。我的问题是验证全部通过后模型值没有更新,所以在我的情况下 {{project.key}} 什么都不显示。
标签: angularjs angularjs-directive angularjs-scope angular-ngmodel