关于javascript:Angular:如何绑定到required / ngRequired

Angular: how to bind to required/ngRequired

我有此要求,无论是否需要。 据我所知,它可以以两种方式使用

1
<my-foo required></my-foo>

要么

1
<my-foo ng-required="data.value > 10"></my-foo>

因此,由于requirengRequire基本上是同一件事,因此您会认为该指令可以执行此操作

HTML:

1
<my-foo ng-require="data.isRequired"></my-foo>

JS:

1
2
3
4
5
6
7
8
...
.directive('myFoo', function () {
    return {
    restrict: 'E',
    scope: {
       required: '='
    }
    ...

演示

好吧,不,这不起作用,scope.requireundefined。 您实际上必须将范围定义更改为

1
2
3
scope: {
    required: '=ngRequired'
}

因此,问题是处理两种情况以使值存储在scope.required中的首选方法是什么? 我应该同时定义两者还是使用链接功能中的attrs?


您基本上可以选择2种方法:

1.支持ng-model的自定义表单元素

如果窥视ng-required指令源代码,您会发现它仅与ng-model控制器有关:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
restrict: 'A',
require: '?ngModel',
link: function(scope, elm, attr, ctrl) {
  if (!ctrl) return;
  attr.required = true; // force truthy in case we are on non input element

  ctrl.$validators.required = function(modelValue, viewValue) {
    return !attr.required || !ctrl.$isEmpty(viewValue);
  };

  attr.$observe('required', function() {
    ctrl.$validate();
  });
}

因此,如果您的自定义指令支持ng-model,那么您已经支持ng-required,即:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
angular.module('test', [])
.directive('myInput', function(){
  return {
    restrict: 'E',
    require: 'ngModel',
    scope: true,
    template: '<button ng-click="changeValue()">Change Value from: {{currentValue}}</button>',
    link: function (scope, element, attrs, ngModelCtrl) {
        ngModelCtrl.$parsers.push(function(val){
          if(!val){
            return null;
          }
          return parseFloat(val, 10) * 100;
        });
        ngModelCtrl.$render = function() {
           scope.currentValue = ngModelCtrl.$viewValue || 'No value';
        };
        scope.changeValue = function read(){
          var newValue = Math.random();
          if(newValue > 0.5){
            ngModelCtrl.$setViewValue(newValue +"");
          } else {
            ngModelCtrl.$setViewValue(null);
          }
          ngModelCtrl.$render();
        };
    }
  };
});

2.包装现有指令并传递ng-required

1
2
3
4
5
6
7
8
9
10
11
12
angular.module('test', [])
  .directive('myFormElement', function() {
      return {
        restrict: 'E',
        scope: {
          model: '=',
          required: '='
        },
        template: 'Enter number: <input type="number" ng-model="data.number" ng-required="required">'
  };

  });
1
2
3
4
5
6
7
8
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">



  <form>
    Is required: <input type="checkbox" ng-model="data.required">
    <my-form-element required="data.required" model="data"></my-form-element>
  </form>