【问题标题】:Angularjs: form validation and input directiveAngularjs:表单验证和输入指令
【发布时间】:2014-02-23 00:25:15
【问题描述】:

我在 AngularJS 应用程序中创建了一个指令,该指令在我的应用程序中生成样式输入。它看起来像这样:

AC.directive('formInput',function ($compile) {
    return {
        transclude: true,
        replace: true,
        scope:{},
        templateUrl: '/views/partials/form/input.html',
        restrict: 'E',
        link: function(scope, element, attrs){

            scope.opts = attrs;

            if(attrs.ngModel){
                element.find('input').attr('ng-model', attrs.ngModel);
                $compile(element.contents())(scope.$parent);
            }

            if(!attrs.type){
                scope.opts.type = 'text';
            }
        }
    };
  }
)

它的模板是:

<label class="acxm-textfield {{opts.cssclass}}">
  <span ng-bind="opts.labeltext"></span>
  <input type="{{opts.type}}" name="{{opts.inputname}}" value="{{opts.inputvalue}}" placeholder="{{opts.placeholder}}" ng-maxlength="{{opts.maxLength}}"/>
</label>

调用很简单:

<form-input ng-model="UserProfile.FirstName" max-length="50" labeltext="{{'GENERAL.name' | translate}}" cssclass="acxm-p-horizontal" inputname="name" inputvalue="{{UserProfile.FirstName}}"></form-input>

我想为此字段创建验证,并添加了错误信息:

<span ng-show="showError(userInfoForm.name,'email')">
                    You must enter a valid email
</span>

而 showError 是:

$scope.showError = function(ngModelController, error) {

    return ngModelController.$error[error];
};

基本上,它是从《Mastering Web Application Development with AngularJS》一书中抄来的。我有一个问题,因为当我在控制台中记录名为userInfoForm 的表单时,我得到了{{opts.inputname}} 而不是名称属性,这里的值应该是“名称”。我做错了什么?

【问题讨论】:

  • 看看我对类似问题的回答:stackoverflow.com/questions/21455695/…
  • 在我发布的链接中声明指令并将name="{{opts.inputname}}"替换为dynamic-name="opts.inputname"
  • Khanh 是的,我可以创建一个指令,但由于我的输入已经是一个指令,我只添加了: element.find('input').attr('name', scope.opts.inputname);它添加了一个名称 attr 但我仍然无法进行验证:/ 在 showError 中,当我尝试访问我的字段时,ngModelController 仍然未定义...这是一个示例:plnkr.co/edit/xKktbdw1dP5elWKnmQMC?p=preview
  • 是的,我认为你的言论很好......嗯,但如何让它发挥作用:)
  • 我发现我的解决方案有效,只是忘记将required 放入我的输入字段。傻我。我张贴作为答案。请看一看。

标签: javascript html angularjs validation


【解决方案1】:

在这里尝试我的dynamic-name 指令:AngularJS dynamic form field validation

name="{{opts.inputname}}" 替换为dynamic-name="opts.inputname"

我还简化了您的演示代码:

app.directive("dynamicName", function($compile) {
  return {
    restrict: "A",
    terminal: true,
    priority: 1000,
    link: function(scope, element, attrs) {
      var name = scope.$eval(attrs.dynamicName);
      if (name) {
        element.attr('name', name);
        element.removeAttr("dynamic-name");
        $compile(element)(scope);
      }
    }
  };
});

app.directive('formInput', function($compile) {
  return {
    replace: true,
    scope: {},
    templateUrl: 'formInput.html',
    restrict: 'E',
    link: function(scope, element, attrs) {
      scope.opts = attrs;


      $compile(element.contents())(scope);
    }
  }
});

表单输入模板:

<label class="acxm-textfield {{opts.cssclass}}">
  <span ng-bind="opts.labeltext"></span>
  <input type="{{opts.type}}" dynamic-name="opts.inputname" ng-model="opts.inputvalue"
  placeholder="{{opts.placeholder}}" 
  ng-maxlength="{{opts.maxLength}}" required/> //use dynamic-name directive to bind dynamic names.
</label>

DEMO(尝试清除文本以查看验证,我使用必需验证进行快速演示,您可以将代码更改为电子邮件验证)。关键是使用dynamic-name 指令。

【讨论】:

  • Khanh 感谢您的帮助,您的示例对您很有帮助! :) 我认为主要问题是我的指令使用了 value 和 ng-model :) 因为唯一的区别是你的指令不使用它:)
【解决方案2】:

这是另一种形式/名称验证指令 stacklink

<form name="myFormName">
  <nested directives of many levels>
  ex: <input ng-repeat=(index, variable) in variables" type="text"
             my-name="{{ variable.name + '/' + 'myFormName' }}"
             ng-model="variable.name" required />
  ex: <select ng-model="variable.name" ng-options="label in label in {{ variable.options }}"
             my-name="{{ variable.name + '/' + 'myFormName' }}"
      </select>
</form

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^

app.directive('rsName', function(){

  var rsNameError = "rsName directive error: "

  return {
    restrict:'A', // Declares an Attributes Directive.
    require: 'ngModel', // ngModelController.

    link: function( scope, elem, attrs, ngModel ){
      if( !ngModel ){ return } // no ngModel exists for this element

      // check rsName input for proper formatting ex. something/something
      checkInputFormat(attrs);

      var inputName = attrs.rsName.match('^\\w+').pop(); // match upto '/'
      assignInputNameToInputModel(inputName, ngModel);

      var formName = attrs.rsName.match('\\w+$').pop(); // match after '/'
      findForm(formName, ngModel, scope);
    } // end link
  } // end return

  function checkInputFormat(attrs){
    if( !/\w\/\w/.test(attrs.rsName )){
      throw rsNameError + "Formatting should be \"inputName/formName\" but is " + attrs.rsName
    }
  }

  function assignInputNameToInputModel(inputName, ngModel){
    ngModel.$name = inputName
  }

  function addInputNameToForm(formName, ngModel, scope){
    scope[formName][ngModel.$name] = ngModel; return
  }

  function findForm(formName, ngModel, scope){
    if( !scope ){ // ran out of scope before finding scope[formName]
      throw rsNameError + "<Form> element named " + formName + " could not be found."
    }

    if( formName in scope){ // found scope[formName]
      addInputNameToForm(formName, ngModel, scope)
      return
    }
    findForm(formName, ngModel, scope.$parent) // recursively search through $parent scopes
  }
});

【讨论】:

    猜你喜欢
    • 2014-08-02
    • 1970-01-01
    • 2021-01-08
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多