简体   繁体   English

角度:选择以编程方式更改ng-model,但不会触发ng-change事件

[英]Angular: select ng-model programmatically changed but ng-change event doesn't fire

Here's my select element: 这是我的选择元素:

 <select class="small-3 columns end statSelect"
          ng-model="chart.categoryAxis"
          ng-change="renderMainChart()"
          ng-options="metric as metric.value for metric in chart.metrics()">
  </select>

I'm changing chart.categoryAxis programmatically every time I click on a button. 每次单击按钮时,我都会以编程方式更改chart.categoryAxis。 However, the ng-change method renderMainChart() doesn't get called. 但是,不会调用ng-change方法renderMainChart()。 Why is this? 为什么是这样?

Here's an example of one of the options: 这是其中一个选项的示例:

<option label="Ad Started" value="object:33">Ad Started</option>

Depending on which button I click, that changes the ng-model value appropriately. 根据我单击的按钮,相应地更改ng-model值。 But the ng-change function renderMainChart() doesn't get called. 但是ng-change函数renderMainChart()没有被调用。

Aelliott1485's answer can be implemented but it would need you to add an extra watch which may not be preferable always. Aelliott1485的答案可以实现,但需要您添加一块额外的手表,但这可能并不总是可取的。


If you are using Angular 1.3 or higher then you can pass a function to the ng-model directive. 如果您使用的是Angular 1.3或更高版本,则可以将函数传递给ng-model指令。

This allows you to specify a method instead of a variable in your ng-model attribute. 这使您可以在ng-model属性中指定方法而不是变量。 The method should take an optional parameter. 该方法应采用可选参数。 If an argument is passed it should store that value, if no argument is passed it should return a value. 如果传递了参数,则应存储该值;如果不传递参数,则应返回一个值。

In this case change your ng-model to call a function instead of accessing a property. 在这种情况下,将您的ng-model更改为调用函数而不是访问属性。

<select class="small-3 columns end statSelect"
      ng-model="chart.categoryAxis()"
      ng-change="renderMainChart()"
      ng-options="metric as metric.value for metric in chart.metrics()">    
</select>

and write a function like this in your controller 并在控制器中编写这样的函数

$scope.categoryAxis = function(value) {
    $scope.ca = value || $scope.ca; // You can also keep a local variable inside the controller instead of a property on $scope
    return $scope.ca;
};

NOTE: You may need to come up with better names. 注意:您可能需要提出更好的名称。

You can utilize $watch() to handle the changing of the value, even when the user doesn't change the value using the select list. 您可以利用$ watch()处理值的更改,即使用户没有使用选择列表来更改值也是如此。 For example: 例如:

 var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope) { var options = [{ value: 'a', id: 1 }, { value: 'b', id: 2 }]; $scope.debugOutput = ''; $scope.chart = { categoryAxis: options[0], metrics: function() { return options; } }; $scope.renderMainChart = function() { console.log('renderMainChart', arguments); }; $scope.pickA = function() { $scope.chart.categoryAxis = options[0]; }; $scope.pickB = function() { $scope.chart.categoryAxis = options[1]; }; $scope.$watch('chart.categoryAxis', function(newValue, oldValue) { $scope.debugOutput += 'categoryAxis changed ' + angular.toJson(oldValue) + ' to ' + angular.toJson(newValue) + "\\n"; }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="plunker"> <div ng-controller="MainCtrl"> <select class="small-3 columns end statSelect" ng-model="chart.categoryAxis" ng-change="renderMainChart()" ng-options="metric as metric.value for metric in chart.metrics()"></select> <div>Selected category Axis: <span>{{ chart.categoryAxis | json }}</span></div> <div> <input type="button" ng-click="pickA()" value="pickA" /> </div> <div> <input type="button" ng-click="pickB()" value="pickB" /> </div> <div>{{ debugOutput }}</div> </div> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM