【问题标题】:ng-disabled doesn't update even if form validity is populated即使填充了表单有效性,ng-disabled 也不会更新
【发布时间】:2014-11-04 17:02:06
【问题描述】:

我创建了一个指令,根据某些标准检查输入是否有效。在这个表单中,我有一个按钮是ng-disabled="form.$invalid"。问题是,即使看起来填充了有效状态,当我的自定义指令更改输入的有效性状态时,我的按钮也没有启用。

这是一个简单的例子:

<div ng-app="app">
  <div ng-controller="fooController">
    <form name="fooForm">
      <input type="text" ng-model="foo" foo>
      <input type="submit" value="send" ng-disabled="fooForm.$invalid">
    </form>
  </div>
</div>

JS(CoffeeScript):

app = angular.module 'app', []

app.directive 'foo', ->
    restrict: 'A'
    require: 'ngModel'
    link: (scope, element, attrs, controller) ->
      element.bind 'keyup', ->
        if controller.$viewValue isnt 'foo'
          controller.$setValidity 'foo', false
        else
          controller.$setValidity 'foo', true

app.controller 'fooController', ($scope) ->
  $scope.foo = 'bar'

简而言之,该指令检查输入的值是否 === 'foo'。如果不是,则将有效性 'foo' 设置为 false,否则设置为 true。

这是一个 jsfiddle (javascript):http://jsfiddle.net/owwLwqbk/

我找到了一个涉及 $apply 的解决方案:http://jsfiddle.net/owwLwqbk/1/

但我想知道是否没有其他更好的方法?国家不应该人口吗?

【问题讨论】:

    标签: angularjs forms validation


    【解决方案1】:

    jqLit​​e 事件处理程序在 Angular 的上下文之外运行,这就是为什么您需要 scope.$apply() 才能工作。

    另一种选择是使用手表...

    link: function(scope, element, attrs, controller) {
        scope.$watch(function () { 
            return controller.$viewValue;
        }, function (newValue) {
            controller.$setValidity('foo', newValue === 'foo');
        });
    }
    

    Fiddle

    【讨论】:

    • 感谢您的解释。我认为使用“$setValidity”,一种角度方法,将有助于填充新的有效性状态。我喜欢你这样做的方式,语法清晰,但我有点担心性能问题。尽可能避免使用 $watch 不是最好的吗?
    【解决方案2】:

    请看下面的演示

    var app;
    
    app = angular.module('app', []);
    
    app.directive('foo', function() {
      return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ctrl) {
    
          ctrl.$parsers.unshift(function(val) {
            console.log(val);
            if (val == "bar") {
              ctrl.$setValidity('foo', true);
            } else {
              ctrl.$setValidity('foo', false);
    
            }
          });
    
    
    
    
    
        }
      };
    });
    
    app.controller('fooController', function($scope) {
      $scope.foo = 'bar';
    });
    .ng-invalid-foo {
      outline: none;
      border: 1px solid red;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    
    
    <div ng-app="app">
      <div ng-controller="fooController">
        [Only "bar" is valid value] <br/>
        <form name="fooForm">
          
          <input type="text" ng-model="foo" foo="">
          <input type="submit" value="send" ng-disabled="fooForm.$invalid" />
        </form>
      </div>
    </div>

    【讨论】:

    • 现在我打算采用您的解决方案,似乎更“原生”。但是,在我的实际情况中,我正在检查输入的值是否与其他输入的值相同(密码重复;))。有没有办法将您的解决方案应用于这种特殊情况?这是一个反映我真实案例的示例:jsfiddle.net/1nm3gc6w/1 我想我必须 $watch 参考值才能执行诸如应用验证器之类的操作,但这可能吗?
    • @Zhouzi 是的,你需要$watch参考值,因为用户可以在输入确认密码后更改密码,请看这里的演示jsfiddle.net/6vtjg7to/2
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 2017-07-07
    • 2022-07-19
    相关资源
    最近更新 更多