加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

AngularJS:在不使用容器的情况下将单个输入元素转换为指令模板

发布时间:2020-12-17 07:00:26 所属栏目:安全 来源:网络整理
导读:我想为我的输入字段创建一个包装器,其中包含一个输入帮助工具提示. 我使用角度1.0.7,如果它是重要的. 我正在使用transclude:true,以及isolate范围,以便同时允许多个不同字段的错误,并仍然保持对外部$scope的ng-model引用. 问题: 当我在input元素上使用this
我想为我的输入字段创建一个包装器,其中包含一个输入帮助工具提示.

我使用角度1.0.7,如果它是重要的.

我正在使用transclude:true,以及isolate范围,以便同时允许多个不同字段的错误,并仍然保持对外部$scope的ng-model引用.

问题:

当我在input元素上使用this指令时,input元素不会克隆(‘Transclude’)到指令模板中.

因此,我在DOM中获得了一个空的div元素,并带有ng-transclude属性.

普拉克:
http://plnkr.co/edit/vFB9ih6x2NBmwhAes3Qh?p=preview

码:

<input data-my-validate-input data-value-required="true" type="password" class="loginItem" placeholder="Password" name="password" data-ng-model="formData.password" data-display-name="Password">

但是当我将这个输入元素包装在span或div中时,子输入元素被超越了,但是我没有在指令处获得对正确的外部ng-model(ctrl)的引用.

<span data-my-validate-input data-value-required="true" data-display-name="Password">
      <input type="password" class="loginItem" placeholder="Password" name="password" data-ng-model="formData.password" >    
</span>

完整代码(链接函数内部的逻辑与问题无关,但我更喜欢发布我的完整代码)

directive('myValidateInput',function() {
    return {
        require: 'ngModel',restrict: 'A',transclude: true,scope: {
            displayName: '@',valueRequired: '@',maxLength: '@',minLength: '@',minLetters: '@',minNumbers: '@'
          },template: '<div class="validationContainer">
                      <div ng-transclude></div>
                      <div class="input-help">
                        <h4>{{fieldErrorDisplay}}</h4>
                        <ul>
                          <li data-ng-repeat="rule in requirementSpec" ng-class="rule.class">
                              {{rule.msg}}
                          </li>
                        </ul>
                      </div>
                    </div>',replace: true,link: function(scope,elm,attrs,ctrl) {
                 var validator = function(viewValue){
                          if(scope.valueRequired && viewValue.length == 0 && (!scope.maxLength && !scope.minLength && !scope.minLetters && !scope.minNumbers)){
                    scope.valid = false;  
                    scope.fieldErrorDisplay = scope.fieldName + ' is required';
                  }
                  else{
                        scope.fieldErrorDisplay = scope.fieldName + ' must meet the following requirements: ';
                        scope.requirementSpec = [];
                        if(scope.minLength){
                          var itemValidity = viewValue.length >= scope.minLength;
                          scope.valid = !itemValidity ? false : scope.valid;
                          var item = {
                            'msg' : 'Must be at least ' + scope.minLength + ' characters long','class' : itemValidity ? 'valid' : undefined
                          };
                          scope.requirementSpec[nameStr].push(item);
                        }
                        else if(scope.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(scope.maxLength){
                          var itemValidity = viewValue.length <= scope.maxLength;
                          scope.valid = !itemValidity ? false : scope.valid;
                          var item = {
                            'msg' : 'Must be ' + scope.maxLength + ' characters long at most  ','class' : itemValidity ? 'valid' : undefined
                          };
                          scope.requirementSpec[nameStr].push(item);
                        }
                        if(scope.minLetters){
                          var itemValidity = (viewValue && /[A-z]/.test(viewValue));
                          scope.valid = !itemValidity ? false : scope.valid;
                          var item = {
                            'msg' : 'Must contain at least ' + scope.minLetters + ' letters','class' : itemValidity ? 'valid' : undefined
                          };
                          scope.requirementSpec[nameStr].push(item);
                        }
                        if(attrs.minNumbers){
                          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) {
                      ctrl.$setValidity(nameStr,true);
                      return viewValue;
                  } else {
                      ctrl.$setValidity(nameStr,false);                    
                      return undefined;
                  }
             }

             scope.requirementSpec = {};

             ctrl.$parsers.unshift(function(viewValue) {
               return validator(viewValue);
             });
             ctrl.$formatters.unshift(function(viewValue) {
               // var before = scope.$eval(attrs.validateBefore);
               if(viewValue && viewValue != "" && viewValue.length > 0)
                 return validator(viewValue);

             });


        });
    }
});

解决方法

解决方案:
$transclude只接受元素的编译内容,因此不是它自己的元素.

显然,我在实现中缺乏对这一重要细节的理解.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读