我使用$watch()
使用以下自定义指令控制required
属性:
app.directive('checkIfRequired', ['$compile', '$timeout', '$parse', function ($compile, $timeout, $parse) {
return {
/*require: '?ngModel',*/
link: function (scope, el, attrs, ngModel) {
var children = $(":input", el);
var saveIsValidationRequired;
//Run the following as early as possible but just wait (using promise) until
// the list of required fields is retrieved from Database
scope.requiredFieldsPromise.then(function(success) {
//If needed, stop validation while adding required attribute
saveIsValidationRequired = scope.isValidationRequired; //Save current flag value
scope.stopExecValidations();
//remove the attribute `check-if-required` to avoid recursive calls
el.removeAttr('check-if-required');
angular.forEach(children, function(value, key) {
if (scope.isFieldRequired(value.id)) {
angular.element(value).attr('required', true);
$compile(value)(scope);
}
//Check if the element is not in "Required" list, and it has a function to control requried, then
//... execute the function using $watch and $parse and add the required attribute accordingly
if (!angular.element(value).prop('required') && value.attributes.hasOwnProperty("check-if-required-expr")) {
var isRequiredExpr = value.attributes["check-if-required-expr"].value;
scope.$watch(function (){
var exprValue = $parse(isRequiredExpr)(scope);
return exprValue;
}
, function (oldValue, newValue){
var isRequired = $parse(isRequiredExpr)(scope);
if (isRequired) {
angular.element(value).prop('required', true);
$compile(value)(scope);
} else {
angular.element(value).prop('required', false);
$compile(value)(scope);
}
var elModel = angular.element(value).controller("ngModel");
elModel.$setViewValue(elModel.$viewValue);
})
}
});
//If saved flag value is true, enable validation
if (saveIsValidationRequired) {
scope.startExecValidations();
}
})
//})
}
};
}]);
基本上,上面的指令检查是否需要子元素,然后它将使用$compile(value)(scope)
添加所需的属性,否则,它将检查是否指定了check-if-required-expr
表达式,如果是的,它将使用$watch()
来计算表达式,并相应地设置所需的属性。
有关详细信息,请参见下图。
一切正常。唯一的问题是,当清除“名称”字段时,应删除“成员#”字段的必需属性,并应清除突出显示,但仍会添加类ng-invalid-required
,这会导致最重要的是。
您可以看到$error
名为NgModelController
的{{1}}对象按照预期的逻辑正确计算。
所以基本上这里的问题是如何确保样式与super_aic_member_number
属性的更改正确同步?
答案 0 :(得分:0)
最后,我设法找到了解决方案。我只是将这个表达式添加到$watch()
属性,而不是使用check-if-required-expr
监视表达式ng-required
,然后,我将编译。
到目前为止,它工作正常。
以下是更新后的代码:
app.directive('checkIfRequired', ['$compile', '$timeout', '$parse', function ($compile, $timeout, $parse) {
return {
/*require: '?ngModel',*/
link: function (scope, el, attrs, ngModel) {
/*if (!ngModel) {
return;
}*/
//debugger;
var children = $(":input", el);
var saveIsValidationRequired;
//Run the following as early as possible but just wait (using promise) until
// the list of required fields is retrieved from Database
scope.requiredFieldsPromise.then(function(success) {
//If needed, stop validation while adding required attribute
saveIsValidationRequired = scope.isValidationRequired; //Save current flag value
scope.stopExecValidations();
//remove the attribute `check-if-required` to avoid recursive calls
el.removeAttr('check-if-required');
angular.forEach(children, function(value, key) {
//debugger; && (value.id != "pi_subject_namex" && value.id != "pi_subj_provincex")
if (scope.isFieldRequired(value.id)) {
angular.element(value).attr('required', true);
//el.removeAttr('check-if-required');
$compile(value)(scope);
}
//Check if the element is not in "Required" list, and it has an expression to control requried, then
//... add the attribute 'ng-required' with the expression specified to the element and compile.
if (!angular.element(value).prop('required') && value.attributes.hasOwnProperty("check-if-required-expr")) {
var isRequiredExpr = value.attributes["check-if-required-expr"].value;
angular.element(value).attr('ng-required', isRequiredExpr);
$compile(value)(scope);
}
});
//If saved flag value is ture, enable validation
if (saveIsValidationRequired) {
scope.startExecValidations();
}
})
//})
}
};
}]);