当模型以编程方式更改时调用 ngChange

ngChange is called when model changed programmatically

当以编程方式更改模型时调用 angular 的 ng-change 时出现问题。

$scope.sendMessage = function() {
    $scope.message = "Message sent";
}

$scope.confirmed = true;
$scope.mySelectBox = $scope.selects[1];

<select ng-model="mySelectBox"
        ng-options="item.name for item in selects track by item.name"
        ng-change="sendMessage()">
</select>

这是代码示例:http://plnkr.co/edit/R4MO86ihMrauHXhpCMxi?p=preview

消息应为空,因为不应调用 sendMessage。模型以编程方式更改。

您正在为控制器中的模型提供值,因此每当您设置与列表匹配的模型值时,它都会调用 ng-change:

查看更新的插件: http://plnkr.co/edit/f3xGmKesLFbzti56WLyH?p=preview

每次模型更改时都会更改 ng-change 回调,并将初始设置视为此类更改。您可能想要做的是 运行 需要的代码 只有在用户与之交互后 。可以查看字段的$touched属性:

<form name="exampleForm" ng-controller="ExampleController">
  <select ng-model="mySelectBox" name="mySelectBox"
          ng-options="item.name for item in selects track by item.name"
          ng-change="sendMessage()">
  </select>
  <p>message = {{message}}</p>
</form>


$scope.sendMessage = function() {
    if ($scope.exampleForm.mySelectBox.$touched) {
        $scope.message = "Message sent";
    }
}

根据文档,你是对的。

https://docs.angularjs.org/api/ng/directive/ngChange

但这似乎是事件连接顺序引起的错误

最好的解决方法 - 借助 js 处理程序 (onchange)

$scope.$watch("mySelectBox", function(a,b) {
    if (a.name!=b.name) {
       $scope.message = "Message sent! (old="+b.name+', new='+a.name+')';
    }
  });

请参阅 plunk http://plnkr.co/edit/2ZbxS1tszppR9SrNqxVB?p=preview

HTH

你可以试试ngModelOptions. See this plunker for reference http://plnkr.co/edit/BdKx62RW5Ls2Iz1H3VR1?p=preview

在我的示例中,我使用了 ng-model-options="{ updateOn: 'change', debounce: { change: 0 } }",它似乎有效。当我更改选择时,它仅运行 ngChange 中提供的功能。在初始化阶段 message 保持为空。