Angular JS:获取ng-change的ng-model

Joa*_*ida 12 javascript angularjs

我有以下HTML

<select ng-model="country" ng-options="c.name for c in countries" ng-change="filterByCountry"></select>
Run Code Online (Sandbox Code Playgroud)

这是由以下对象和国家列表提供的

$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} ...];
Run Code Online (Sandbox Code Playgroud)

当我更改我的下拉值时,我期望在filterByCountry函数内更新我的模型($ scope.country),但事实并非如此.我在这里错过了什么?

Jus*_*ner 11

ng-change该处理之前触发ng-model实际更新.如果您希望filterByCountry每次$scope.country更改时(而不是仅仅在下拉列表更改时)被触发,您应该使用以下代码:

$scope.$watch('country', filterByCountry);
Run Code Online (Sandbox Code Playgroud)

我总是发现$scope在可能的情况下对我而不是DOM事件的变化做出反应更有用.

  • 你的答案是对的(尽管我在提出问题之前尝试过这个解决方案).我的问题是我使用ng-if来显示下拉列表.我改为ng-show,现在工作正常.谢谢 ;) (3认同)
  • @JustinNiessner,这是不正确的.更新`ng-model`后会触发`ng-change`:http://plnkr.co/edit/JgvNTTJWAq2hSkzky6nu?p = preview.实际上,如果您只想对用户发起的更改做出反应,那么添加`$ watch`会不必要地花费 (2认同)

Jam*_*son 10

对于来到这里的其他人来说, ng-change实际上是在设置了模型值之后调用的.

为什么?
让我们看看它何时被调用.从角度源代码,ng-change只是一个带有此指令定义对象(DDO)的属性指令.

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

由此我们看到该ng-change指令非常简单.所有这一切ng-change='<expr>'确实是一个函数添加到年底的$viewChangeListeners计算结果<expr>通过$范围.$ EVAL.

好的...那么什么时候调用ViewChangeListeners?

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

新值将应用于$ modelValue,然后应用于ng-model属性中指定的表达式.最后,调用$ viewChangeListeners列表中的所有已注册的更改侦听器.

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

另请注意,此行为在所有版本的角度中都相同.ng-change自v1.2以来,定义没有改变.

  • 现在为什么我看到相反的行为? (3认同)