Angular JS:在ng-change上获取ng-model

Angular JS: get ng-model on ng-change

本文关键字:获取 ng-model ng-change JS Angular      更新时间:2023-09-26

我有以下HTML

<select ng-model="country" ng-options="c.name for c in countries" ng-change="filterByCountry"></select>

由以下对象提供,其中包含国家列表

$scope.countries = [{name:Afeganistão, country:AF}, {name:África do Sul, country:ZA}, name:Albânia, country:AL}, {name:Alemanha, country:DE}, {name:Andorra, country:AD} ...];

当我改变我的下拉值,我期待我的模型($scope.country)被更新,内部filterByCountry函数,但它不是。我遗漏了什么?

在实际更新ng-model之前触发ng-change处理程序。如果您希望每次$scope.country更改时都触发filterByCountry(而不仅仅是当下拉菜单更改时),您应该使用以下命令:

$scope.$watch('country', filterByCountry);

我总是发现在可能的情况下,对$scope的变化作出反应比对DOM事件作出反应更有用。

给在座的各位,在模型值设置后,ng-change实际上被称为

为什么?
让我们看看它什么时候被调用。从angular源代码来看,ng-change只是一个带有该指令定义对象(DDO)的属性指令。

{
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attr, ctrl) {
      ctrl.$viewChangeListeners.push(function() {
        scope.$eval(attr.ngChange);
      });
    }
}

由此可见,ng-change指令非常简单。ng-change='<expr>'所做的只是在$viewChangeListeners的末尾添加一个函数,通过$scope.$eval.

计算<expr>的值。

好吧…什么时候调用viewchangelistener ?

好吧,如果我们看看ngModel的文档。NgModelController:

新值将应用于$modelValue,然后是ng-model属性中指定的表达式。最后,在$ viewchangelistener列表中,所有注册的更改侦听器都被调用

因此,ngChange的viewChangeListener将在值应用于$modelValue之后被调用。因此,回调将在模型设置后被调用。

还要注意,这个行为在所有版本的angular中都是一样的。ng-change的定义自v1.2以来没有改变。

正如James Lawson指出的,

ng-change实际上是在模型值设置后调用的。

如果你还在问

为什么我看到了相反的行为?

那么你应该知道$scope是原型继承自它的父变量,如果你的作用域变量只是一个简单的类型(字符串,布尔等),那么它将在子作用域中被覆盖为由ng-model指令 设置的值。要查看子作用域是在哪里创建的(在哪个DOM元素上),您可以打开开发工具并在元素
上查找class="ng-scope"