指令链接功能取决于XHR请求

时间:2013-10-08 13:49:24

标签: angularjs angularjs-directive

我有以下验证指令:

directive('myValidate', function($timeout) {
    return {
        require: 'ngModel',
        link: function(scope, elm, attrs, ctrl) {
              if(!scope.requirementSpec){
                scope.requirementSpec = {}; 
              }
              if(Boolean(attrs.valueRequired) || Boolean(attrs.minLength) && elm[0].value != ""){
                console.log(scope.model[attrs.name]);
                ctrl.$setValidity(attrs.name, false);
                // elm.removeClass('ng-valid').addClass('ng-invalid');
                }


              elm.on('focus', function(){
                console.log(elm);
                console.log(ctrl);
                var form = elm.parents().find('form');
                // $timeout(function(){$ctrl.$dirty = true;}, 0);
              });
            ctrl.$parsers[0] = (function(viewValue) {

              scope.valid = true;
              scope.fieldName = attrs.name;
              var nameStr = attrs.name + '';
              var nameObj = nameStr.split('_');
              for(var i = 0; i < nameObj.length; ++i){
                nameObj[i] = nameObj[i].substr(0, 1).toUpperCase() + nameObj[i].slice(1);
              }
              var nameStrParsed = nameObj.join(' ');
              scope.fieldErrorDisplay = Boolean(nameStrParsed) ? nameStrParsed : 'This field';
              if(attrs.valueRequired && viewValue.length == 0 && !attrs.minLength){
                  scope.valid = false;  
                  scope.requirementSpec[nameStr] = [{
                    'msg' : scope.fieldErrorDisplay + ' is required',
                    'class' : undefined
                  }];
                }
                else{
                      // scope.fieldErrorDisplayObj[nameStr] = scope.fieldErrorDisplay + ' must meet the following requirements: ';
                      scope.requirementSpec[nameStr] = [];
                      if(attrs.minLength){
                        var itemValidity = viewValue.length >= attrs.minLength;
                        scope.valid = !itemValidity ? false : scope.valid;
                        var item = {
                          'msg' : 'At Least ' + attrs.minLength + ' Chars',
                          'class' : itemValidity ? 'valid' : undefined
                        };
                        scope.requirementSpecrequirementSpec[nameStr].push(item);
                      }
                      else if(attrs.valueRequired){
                        var itemValidity = viewValue && viewValue.length >= 1;
                        scope.valid = !itemValidity ? false : scope.valid;
                        var item = {
                          'msg' : 'This field must be filled',
                          'class' : itemValidity ? 'valid' : undefined
                        };
                        scope.requirementSpec[nameStr].push(item);
                      }
                      if(attrs.maxLength){
                        var itemValidity = viewValue.length <= attrs.maxLength;
                        scope.valid = !itemValidity ? false : scope.valid;
                        var item = {
                          'msg' :  attrs.maxLength + ' Chars At Most  ',
                          'class' : itemValidity ? 'valid' : undefined
                        };
                        scope.requirementSpec[nameStr].push(item);
                      }
                      if(attrs.minLetters){
                        var itemValidity = (viewValue && /[A-z]/.test(viewValue));
                        scope.valid = !itemValidity ? false : scope.valid;
                        var item = {
                          'msg' : 'Must contain at least ' + attrs.minLetters + ' letters',
                          'class' : itemValidity ? 'valid' : undefined
                        };
                        scope.requirementSpec[nameStr].push(item);
                      }
                      if(attrs.minNumbers){focus
                        var itemValidity = (viewValue && /\d/.test(viewValue));
                        scope.valid = !itemValidity ? false : scope.valid;
                        var item = {
                          'msg' : 'Must contain at least' + attrs.minNumbers + ' numbers',
                          'class' : itemValidity ? 'valid' : undefined
                        };
                        scope.requirementSpec[nameStr].push(item);
                      }
                }

                if(scope.valid) {
                  var errorsPresent = false;
                  for(var i = 0; i < scope.requirementSpec[nameStr].length; i++){
                    if(!scope.requirementSpec[nameStr][i].class){
                      errorsPresent = true;
                    }
                  }
                  scope.requirementSpec[nameStr] =  errorsPresent ? scope.requirementSpec[nameStr] : [];
                    ctrl.$setValidity(nameStr, true);
                    elm.removeClass('ng-required-invalid').removeClass('validatorError').removeClass('ng-invalid').addClass('ng-valid');
                    return viewValue;
                } else {
                    ctrl.$setValidity(nameStr, false);                    
                    return undefined;
                }

            });
        }
     };

}).

正如您所看到的,在link函数中,我检查我在其上应用此指令的input元素的值是否为空,并将此元素设置为valid为false。

当我使用此指令验证编辑表单时会出现问题,在该表单中,值将通过对REST资源的XHR请求进行检索。

我的问题是:如何处理这个问题,并将这个逻辑绑定到字段的ng-model上,而不是单独观看每个字段,这将是一个可怕的浪费。

也许我可以让$解析器对字段模型的变化做出反应,而不仅仅是直接用户输入?。

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您正在尝试侦听对ngModel / Form元素所做的更改?

尝试在你的ngModel上添加一个$ watch监听器,如下所示:

scope.$watch(attrs.ngModel, function(val) {
    // React the the value changes
})

答案 1 :(得分:0)

答案在Angularjs文档中提供了表单: http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController# $格式化

$ formatters是模型与指令评估的值之间的管道。

请关闭。