AngularJS:在更改select元素之前调用ng-change

时间:2015-12-02 06:20:11

标签: javascript angularjs angularjs-directive

据我所知,ng-changeng-model元素中实际更改之前被调用select。以下是重现问题的一些代码:

angular.module('demo', [])
  .controller('DemoController', function($scope) {
    'use strict';

    $scope.value = 'a';
    $scope.displayValue = $scope.value;

    $scope.onValueChange = function() {
      $scope.displayValue = $scope.value;
    };
  })
  .directive("selector", [
    function() {
      return {
        controller: function() {
          "use strict";
          this.availableValues = ['a', 'b', 'c'];
        },
        controllerAs: 'ctrl',
        scope: {
          ngModel: '=',
          ngChange: '='
        },
        template: '<select ng-model="ngModel" ng-change="ngChange()" ng-options="v for v in ctrl.availableValues"> </select>'
      };
    }
  ]);
<html lang="en">

<head>
  <meta charset="utf-8">
</head>

<body>
  <div ng-app="demo" ng-controller="DemoController">
    <div selector ng-model="value" ng-change="onValueChange">
    </div>
    <div>
      <span>Value when ng-change called:</span>
      <span>{{ displayValue }}</span>
    </div>
  </div>

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
  <script src="demo.js"></script>
</body>

</html>

如果你运行它,你应该改变组合框2次(例如'b'(必须不同于默认值),然后'c')。

  • 第一次,没有任何反应(但文本中显示的值应更改为与选择相匹配)。
  • 第二次,该值应更改为上一个选择(但应该已设置为当前选择)。

这听起来与以前的几个帖子非常相似:AngularJS scope updated after ng-changeAngularJS - Why is ng-change called before the model is updated?。不幸的是,我无法重现第一个问题,而第二个问题是通过我已经使用的不同范围绑定解决的。

我错过了什么吗?有解决方法吗?

2 个答案:

答案 0 :(得分:2)

最好不要在指令中使用相同的模型值。创建另一个innerModel,它应该在指令中使用并更新&#34; parent&#34;提供NgModelController时需要的模型。

使用此解决方案,您不会破解ng-change行为 - 只需使用Angular已提供的内容。

&#13;
&#13;
angular.module('demo', [])
  .controller('DemoController', function($scope) {
    $scope.value = 'a';
    $scope.displayValue = $scope.value;
    $scope.onValueChange = function() {
      $scope.displayValue = $scope.value;
    };
  })
  .directive("selector", [
    function() {
      return {
        controller: function() {
          this.availableValues = ['a', 'b', 'c'];
        },
        require: 'ngModel',
        controllerAs: 'ctrl',
        scope: {
          'ngModel': '='
        },
        template: '<select ng-model="innerModel" ng-change="updateInnerModel()" ng-options="v for v in ctrl.availableValues"> </select>',
        link: function(scope, elem, attrs, ngModelController) {
          scope.innerModel = scope.ngModel;
          scope.updateInnerModel = function() {
            ngModelController.$setViewValue(scope.innerModel);
          };
        }
      };
    }
  ]);
&#13;
<div ng-app="demo" ng-controller="DemoController">
  <div selector ng-model="value" ng-change="onValueChange()">
  </div>
  <div>
    <span>Value when ng-change called:</span>
    <span>{{ displayValue }}</span>
  </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
&#13;
&#13;
&#13;

this answer的启发。

答案 1 :(得分:0)

这是一个摘要问题..只需使用onValueChange包裹$timeout操作:

$scope.onValueChange = function() {
   $timeout(function(){
       $scope.displayValue = $scope.value;        
   });
};
  • 不要忘记在控制器中注入$timeout

...或者您可以查看link如何为自定义指令实施ng-change