javascript 指令和表单验证中的 AngularJS 动态必需属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28207288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 08:35:34  来源:igfitidea点击:

AngularJS dynamic required attribute in directive and form validation

javascriptangularjsvalidation

提问by olingern

I have a directive that receives whether an element should be required or not from a REST api. Right now, I can't seem to get the form to invalidate when an attribute is set to required.

我有一个指令,可以从 REST api接收是否需要元素。现在,当属性设置为必需时,我似乎无法使表单失效。

So, in essence I'm able to dynamically add the 'required' attribute from the directive below, but it doesn't invalidate the form. Looking through chrome I see that, even though the required attribute exists, a required entry in the $error array doesn't exist.

因此,从本质上讲,我可以从下面的指令中动态添加“必需”属性,但它不会使表单无效。查看 chrome 我看到,即使 required 属性存在,$error 数组中的必需条目也不存在。

app.directive('requireiftrue', function ($compile) {
    return {
        require: '?ngModel',
        link: function (scope, el, attrs, ngModel) {
            if (!ngModel) {
                return;
            }

            if(attrs.requireiftrue==="true"){
                console.log('should require');
                el.attr('required', true);
                $compile(el.contents())(scope);
            }
            else{
                console.log('should not require');   
            }
        }
    };
});

Here's a jsfiddleto illustrate the problem. And, here's sample JSON returned from my rest API

这是一个jsfiddle来说明这个问题。而且,这是从我的其余 API 返回的示例 JSON

{
    race: false,
    martialStatus: true,
}

EDIT:While the accepted answer got me up and running, I still had a good bit of finagling to do.

编辑:虽然接受的答案让我开始工作,但我仍然有很多事情要做。

Namely: 1. Resolving a deferred promise to ensure that my form actually receives the required fields to validate 2. observing my 'requireiftrue' attribute

即: 1. 解决延迟承诺以确保我的表单实际收到需要验证的字段 2. 观察我的“requireiftrue”属性

My solution

我的解决方案

module config:

模块配置:

function config($stateProvider) {
    $stateProvider

    .state('testState', {
        url: '/test/form',
        controller: 'TestCtrl',
        templateUrl: 'test/form/testForm.tpl.html',
        resolve: {
            formDefaultService: function getFormDefaults($q, dataservice) {
                // Set up a promise to return
                var deferred = $q.defer();
                var myData = dataservice.getFormDefaults();
                deferred.resolve(myData);

                return deferred.promise;
                //return 
            }
        },

        data: {
            pageTitle: 'Test Info'
        }
    });
}

And, finally the directive / HTML that receives api data:

最后是接收 api 数据的指令/ HTML:

Directive:

指示:

.directive('requireiftrue', function ($compile) {
    return {
        require: '?ngModel',
        link: function (scope, el, attrs, ngModel) {
            if (!ngModel) {
                return;
            }
            attrs.$observe('requireiftrue', function(value){ 
                if(value==="true"){
                    el.attr('required', true);
                    el.removeAttr('requireiftrue');
                    $compile(el[0])(scope);
                }
            });
        }
    };
});

HTML:

HTML:

<input max="40"
requireiftrue={{defaults.validation.name}}
validNumber
id="name"
name="name"
type="text"
ng-model="test.name"
class="form-control">

回答by Aviv Shaked

You had two issues: The first is el.contents() returned an empty array. so The first thing you should do is change it to el[0]. But had el.contents() worked you would hav had a much more serious problem. You would have been trying to compile a directive that has itself as a directive which would lead to an infinite loop (well until the browser crashed any way). So here is the revised code:

你有两个问题:第一个是 el.contents() 返回一个空数组。所以你应该做的第一件事就是把它改成 el[0]。但是如果 el.contents() 工作,你会遇到更严重的问题。您可能一直在尝试编译一个指令,该指令将自身作为一个指令,这将导致无限循环(直到浏览器以任何方式崩溃)。所以这是修改后的代码:

var app = angular.module('form-example', []);

app.directive('requireiftrue', function ($compile) {
    return {
        require: '?ngModel',
        link: function (scope, el, attrs, ngModel) {
            if (!ngModel) {
                return;
            }

            if(attrs.requireiftrue==="true"){
                console.log('should require');
                el.attr('required', true);
                el.removeAttr('requireiftrue');
                $compile(el[0])(scope);
            }
            else{
                console.log('should not require');   
            }
        }
    };
});

I should note however that now this directive is a one-off. If the model will change, the directive will not be on the element any longer to deal with it.

但是我应该注意,现在这个指令是一次性的。如果模型会改变,指令将不再在元素上处理它。

回答by Rajeshwar

Instead of using a directive, use ng-initto initialize requireiftrue. and assign this value to ng-requiredlike ng-required="requireiftrue"as shown below. As you said you are getting the data from rest api, you can initialize requireiftruewith the value you are getting from api, instead of true or false as shown in example below.

而不是使用指令,使用ng-init来初始化requireiftrue。并将此值分配给ng-requiredlike ng-required="requireiftrue",如下所示。正如您所说,您是从 rest api 获取数据,您可以requireiftrue使用从 api 获取的值进行初始化,而不是如下例所示的 true 或 false。

Hope this helps you.

希望这对你有帮助。

Updated fiddle http://jsfiddle.net/zsrfe513/3/

更新小提琴 http://jsfiddle.net/zsrfe513/3/

<form ng-app="form-example" name='fo' class="row form-horizontal" novalidate>
<div class="control-group" ng-form="testReq">
    <h3>Form invalid: {{testReq.$invalid}}</h3>
 <label class="control-label" for="inputEmail">Email</label>
 <div class="controls" ng-init='requireiftrue = true'>
   <input id="inputEmail" placeholder="Email" ng-model="email"  name='ip' ng-required='requireiftrue'>

    <span ng-show="testReq.ip.$dirty && testReq.ip.$error.required">
        Required.
    </span>
   </div>
 </div>
</form>

回答by Michael Coleman

Try:

尝试:

1. 将requiredrequired指令添加到要应用验证的输入中





<input id="inputEmail" class="requireiftrue" placeholder="Email" 
    ng-model="email" requireiftrue="true" required>
2 将指令定义为类型classclass并将指令类添加到 HTML 输入字段

JS

JS

app.directive('requireiftrue', function ($compile) {
   return {
    restrict: 'C',
    require: '?ngModel',
    .....

HTML

HTML

<input id="inputEmail" class="requireiftrue" placeholder="Email" ng-model="email" requireiftrue="true" required>

here is a update of your fiddle- http://jsfiddle.net/4fb6wg30/

这是你的小提琴的更新- http://jsfiddle.net/4fb6wg30/

回答by Support JDWebapps

You just need to add the "required" attribute to the input.

您只需要在输入中添加“required”属性。

<input max="40"
requireiftrue={{defaults.validation.name}}
validNumber
id="name"
name="name"
type="text"
ng-model="test.name"
class="form-control"
required="required">

回答by Richard Torcato

I used <input ng-required="true">worked fine for my angular validation component.

我用<input ng-required="true">我的角度验证组件工作得很好。

If your using the new angular component make sure to pass in required: "@" instead of required: "="

如果您使用新的 angular 组件,请确保传入 required: "@" 而不是 required: "="

scope: {
      required: '@'
    }

I also took this further and required integer and min/max validation the same way.

我也更进一步,并以同样的方式要求整数和最小/最大验证。