我的情况是,ng-model值有时可能不存在于选择下拉列表的ng-options列表中(例如,不再将公司保存在记录中的用户的ID)。 AngularJS的行为是它为下拉列表添加了一个空选项,但没有将其标记为Invalid或Error,这使得难以验证。我找到了一个解决方案here,它使用指令在加载页面时处理这种情况。因为我使用API调用获取用户ID和列表,所以在研究之后我添加了一个$ watch以确保在检查之前加载了数据,但我似乎无法让它工作。有人可以帮我弄清楚我的代码有什么问题吗?看来$ validators函数中的代码没有被正确调用或者一直调用。我需要的是能够在用户ID不在选择列表中时显示消息,但是当用户从下拉列表中选择一个名称时,该消息应该消失。
这是我的代码的相关部分:
<div ng-app="RfiApp" ng-controller="RfiControllerRef" class="col-sm-12">
<form class="pure-form pure-form-aligned" name="frm" method="post"
autocomplete="off">
<div class="form-horizontal">
<div class="form-group">
<label class="control-label col-md-2" for="bsa_analyst_user_id">BSA Analyst</label>
<div class="col-md-10">
<select class="form-control" id="bsa_analyst_user_id" name="bsa_analyst_user_id" ng-model="rfi.bsa_analyst_user_id" ng-options="s.value as s.name for s in BsaAnalysts | orderBy: 'name'" valid-values="BsaAnalysts" required>
<option value="">--Select--</option>
</select>{{frm.bsa_analyst_user_id.$error}} - {{frm.bsa_analyst_user_id.$invalid}} - {{rfi.bsa_analyst_user_id}}
<div class="text-danger"
ng-show="frm.bsa_analyst_user_id.$invalid"
ng-messages="frm.bsa_analyst_user_id.$error">
<div ng-message="required">BSA Analyst is required</div>
<div ng-message="validValues">BSA Analyst in database not valid or not in BSA Unit selected</div>
</div>
</div>
</div>
</div>
</form>
</div>
.JS代码:
RfiApp.directive('validValues', function () {
return {
scope: {
validValues: '=',
model: '=ngModel'
},
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attributes, ngModel) {
scope.$watch('[model,validValues]', function (newVals) {
if (newVals[0] && newVals[1]) {
var values = angular.isArray(scope.validValues)
? scope.validValues
: Object.keys(scope.validValues);
ngModel.$$runValidators(newVals[0], values, function () { });
ngModel.$validators.validValues = function (modelValue) {
var result = values.filter(function (obj) {
return obj.value == modelValue;
});
var ret = result.length > 0;
return ret;
}
}
});
}
}
});
$scope.GetDropdownValues = function () {
var a = 1;
DropdownOptions.get(
function (response) {
//... other code ommitted
$scope.UserAnalysts = response.UserAnalystsList;
},
function () {
showMessage('error', "Error");
}
);
};
$scope.GetExistingRfi = function () {
NewRfiResource.get({ rfiId: $scope.rfiId },
function (response) {
$scope.rfi = response.rfi;
$scope.ButtonText = "Save";
},
function (response) {
showMessage('error', response.data.Message);
$scope.GetNewRfi();
}
);
};
$scope.GetDropdownValues();
if ($scope.rfiId != "0") {
$scope.GetExistingRfi();
}
else {
$scope.GetNewRfi();
}
谢谢!