更改`ng-required`是否会调用`ng-change`?(涉及IT技术)

9

我在使用 AngularJS 1.5.8 的应用程序中遇到了奇怪的行为:

plunker (https://plnkr.co/edit/zaHVJeK8hdxk2gaOL9Pf?p=preview) 和视频 (http://recordit.co/eszvfdfC9S)

  • 步骤 1。 最初更改 ng-required 不会调用 ng-change 函数
  • 步骤 2。 在更改 input 并删除它们后(input 为空),ng-required 会调用 ng-change 函数

期望的行为?

  • 步骤 2。 在更改 input 并删除它们后(input 为空),ng-required 不应该调用 ng-change 函数。就像最初一样,以及当输入具有某些值时

请告诉我这是不是一个 bug。如果不是,为什么更改 ng-required 不总是或根本不调用 ng-change

答案已找到-------------------------------------------------------------------------------------------------------

NgModelController 有两个属性:$viewValue(由用户输入的值)和 $modelValue(绑定到模型的值)。当用户输入的值未通过验证时,NgModelController 将模型设置为 undefined。

在 AngularJS 1.3 中,他们添加了 ng-model-options 指令。它允许您配置何时以及如何更新模型。您可以使用 allowInvalid 选项防止将模型设置为 undefined:

ng-model-options="{allowInvalid: true}"

好问题! - Farzad Salimi Jazi
确实很好。感觉像是一个bug,因为行为不稳定,而且升级到1.6.0-rc.1也没有解决它。 - Gray Fox
4个回答

7

你应该添加

        ng-model-options="{allowInvalid: true}"

因此,最终结果将是:
<input type="text" 
    ng-change="$ctrl.onChange()" 
    ng-required="$ctrl.isRequired"
    ng-model-options="{allowInvalid: true}"
    ng-model="$ctrl.val"
    />

2
这是因为当ng-required设置为false时,ng-required会将附加模态值从空白更改为未定义,由于此模态更改,因此会触发ng-change。
在plunker中检查,我已经console.log了输入的值,您可以清楚地看到模态的更改。
angular.
  module('myApp', []).
  component('greetUser', {
    templateUrl: 'tmpl.html',
    controller: function GreetUserController() {
      this.output='';
      this.isRequired = false; 

       console.log(this.val);

      this.onChange = function() {

        console.log(this.val);
        this.output+='Changed\n';
      }
    }
  });

plunker: https://plnkr.co/edit/6IeIjIDahcmBIU4KSASJ?p=preview

现在问题来了,为什么在加载/第一次更改事件时不会触发?因为我们使用的是this对象而不是$scope。

这里有一个很好的例子,解释了为什么在至少手动输入一次输入值之前,更改事件不会触发:'this' vs $scope in AngularJS controllers

简而言之,这是由于ng-change/ng-model与作用域变量一起工作。一旦您手动输入输入元素的值,模型绑定就会与作用域发生,ng-change事件开始触发。


谢谢您的回答,但那不正确。请检查正确的答案。 - Ivan
谢谢 :) 我的回答更加强调了为什么会发生这种情况。不幸的是,这不是你要寻找的答案。 - Deep
1
我明白你的意思,而且是正确的,我已经再次检查过了。谢谢你的帮助。但我仍然认为这是Angular中不正确的行为。 - Ivan
1
这是我找到的内容: NgModelController有两个属性:$viewValue(用户输入的值)和$modelValue(绑定到您的模型的值)。当用户输入的值未通过验证时,NgModelController会将模型设置为未定义。 这正是您所解释的,谢谢。 - Ivan

0

我觉得你有误解。

ng-requiredng-change 是不同的东西,它们有不同的目的,并且彼此之间没有调用关系。

ng-change 会在输入框发生变化时自动调用你的函数,无论它是否为空。它会根据输入框中的变化来调用你的方法。

ng-required 只是检查值是否为空,如果为空,则将其标记为无效。

为了达到你想要的效果,你必须在 onChange 函数内部检查有效性。

this.onChange = function() {

    if( !$scope.$ctrl.form.$valid ) return;

    this.output+='Changed\n';
}

你写了 and not calling each other,但问题在于:ng-required 调用了 ng-change - Ivan
我无法检查表单是否有效,因为它是动态的,而且有很多其他的有效/无效字段。 - Ivan

0

我认为这就是原因。在ng-change中加入一个警告,像这样。

this.onChange = function() {
        alert(this.val);
        this.output+='Changed\n';
      }

当你完成一个盒子并清空它时,两个值之间的值会改变:
undefined  when is required 
''         when is not required 

通过更改单选框,您调用ng-change, 在开始时您有

但是,当您还没有开始在文本框中输入时,单选框不会更改输入值,因为ng-change是针对输入的。 在开始时,我们有undefined --> undefined,所以什么也没有改变。 然后当您清空输入时,您有'' ---> undefined

实际上,如果您将此放入控制器中,您也会在开始时调用ng-change。

this.val ='';

如果你用这个替换你的控制器,你会发现 ng-change 甚至在一开始就被调用了。

angular.
  module('myApp', []).
  component('greetUser', {
    templateUrl: 'tmpl.html',
    controller: function GreetUserController() {
      this.output='';
      this.isRequired = false; 
      this.val ='';
      this.onChange = function() {
        this.output+='Changed\n';
      }
    }
  }); 

我根本不需要调用 ng-change。这就是问题所在。但是我已经找到了答案。 - Ivan
@Matiishyn 我并不是期望被选为答案,只是想看看为什么会发生这种情况,很高兴看到你得到了答案,其实我也学到了。太棒了! - Farzad Salimi Jazi
我也是) 谢谢你的帮助! - Ivan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接